/* ============================================================
   VISIONHUB — estilos das telas do hub (progresso, calendário, listas,
   fichas, formulários)
   O cabeçalho, o menu do usuário e o rodapé saíram daqui para o
   chrome.css, que as ferramentas também carregam; a barra lateral e o
   enquadramento da página moram no sidebar.css.
   ============================================================ */

    *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

    body {
      font-family: var(--font-sans);
      background: var(--bg-0);
      color: var(--fg-1);
      min-height: 100vh;
      display: flex;
      flex-direction: column;
      transition: background var(--dur-2), color var(--dur-2);
    }

    /* Subtle brand glow in the background */
    body::before {
      content: "";
      position: fixed;
      top: -20%;
      left: 50%;
      transform: translateX(-50%);
      width: 900px;
      height: 900px;
      background: radial-gradient(circle, rgba(169,147,255,0.14), transparent 62%);
      pointer-events: none;
      z-index: 0;
    }

    /* ── A tela inicial ──────────────────────────── */
    /* A hero saiu daqui junto com o markup dela: a tela é o mês, e ela
       empurrava o mês para baixo da dobra. O que resta é o enquadramento —
       um bloco que desce, do seletor de mês até o fim do calendário. */
    .hub-home {
      padding: var(--space-5) var(--space-5) var(--space-6);
    }

    /* ── A moldura do conteúdo ───────────────────── */
    main {
      position: relative;
      z-index: 1;
      flex: 1;
      width: 100%;
      max-width: 1120px;
      margin: 0 auto;
      padding: var(--space-5) var(--space-6) var(--space-9, 96px);
    }

    .section-label {
      display: flex;
      align-items: center;
      gap: var(--space-3);
      font-size: 0.72rem;
      font-weight: 600;
      letter-spacing: 0.12em;
      text-transform: uppercase;
      color: var(--fg-3);
      margin-bottom: var(--space-5);
    }
    .section-label::after {
      content: "";
      flex: 1;
      height: 1px;
      background: var(--border-1);
    }

    .tag {
      font-size: 0.68rem;
      font-weight: 600;
      letter-spacing: 0.06em;
      text-transform: uppercase;
      padding: 4px 10px;
      border-radius: var(--radius-pill);
    }
    .tag.soon { background: var(--surface-overlay); color: var(--fg-4); }
/* Papel do usuário — preenchimento sólido, não tingido como os outros
   selos: o papel é a identificação principal da conta, e os demais
   (superusuário, Django admin, inativa) são qualificadores dela.

   Admin e Equipe ficam na família roxa, em dois pesos; Cliente sai dela,
   porque a distinção que importa num relance é interno × externo.
   As cores do texto são fixas nos dois temas — o contraste é com o
   preenchimento, não com o fundo da página. */
.tag.role.is-admin   { background: var(--vision-purple-strong); color: var(--vision-white); }
.tag.role.is-equipe  { background: var(--vision-purple-light);  color: var(--vision-ink); }
.tag.role.is-companye { background: var(--vision-blue);          color: var(--vision-white); }

    @media (max-width: 560px) {
      main { padding: var(--space-4) var(--space-5) var(--space-8); }
    }

/* Estado vazio de uma lista — cronogramas, anexos e usuários de uma
   empresa dizem por aqui que ainda não têm nada. */
.empty-state {
  border: 1px dashed var(--border-1); border-radius: var(--radius-md);
  padding: var(--space-6) var(--space-5);
  text-align: center; color: var(--fg-2); font-size: 15px;
}
.empty-state strong { color: var(--fg-1); display: block; margin-bottom: 6px; font-size: 16px; }

/* ============================================================
   LOGIN
   ============================================================ */
.auth {
  flex: 1; display: grid; place-items: center;
  padding: var(--space-6) var(--space-5) var(--space-8);
}
.auth-card {
  width: 100%; max-width: 380px;
  background: var(--bg-1); border: 1px solid var(--border-1);
  border-radius: var(--radius-md); padding: var(--space-6);
}
.auth-card h1 {
  font-family: var(--font-display); font-size: 30px; font-weight: 400;
  color: var(--fg-1); margin-bottom: 6px;
}
.auth-card .sub { font-size: 14px; color: var(--fg-2); margin-bottom: var(--space-5); }

.auth-card label {
  display: block; font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--fg-2); margin-bottom: 7px;
}
.auth-card .field {
  width: 100%; padding: 11px 13px; margin-bottom: var(--space-4);
  background: var(--bg-0); color: var(--fg-1);
  border: 1px solid var(--border-1); border-radius: var(--radius-sm);
  font-family: var(--font-sans); font-size: 15px;
  transition: border-color var(--dur-1);
}
.auth-card .field:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(169,147,255,.16);
}
.auth-card .btn {
  width: 100%; padding: 12px; margin-top: var(--space-2);
  background: var(--accent); color: #14101f;
  border: none; border-radius: var(--radius-sm);
  font-family: var(--font-sans); font-size: 15px; font-weight: 600;
  cursor: pointer; transition: filter var(--dur-1);
}
.auth-card .btn:hover { filter: brightness(1.08); }

.auth-error {
  background: rgba(255,107,107,.1); border: 1px solid rgba(255,107,107,.35);
  color: #ff9d9d; border-radius: var(--radius-sm);
  padding: 10px 13px; margin-bottom: var(--space-4); font-size: 14px;
}
.field-error { display: block; margin: -10px 0 var(--space-4); font-size: 13px; color: #ff9d9d; }

/* ============================================================
   BOTÃO E CAMPO — a base, para quem não está dentro de um formulário
   ============================================================ */
/* `.btn` e `.field` nasceram escopados em `.auth-card` e `.form-row`, que
   era onde eles existiam. Fora dali — no rodapé do popup de um post, por
   exemplo — a classe não pintava nada e o controle saía no desenho cru do
   navegador, fora do design system.
   A base fica aqui; as regras escopadas continuam valendo por
   especificidade, então nenhuma tela existente muda de aparência. */

.btn {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 11px var(--space-5);
  background: var(--accent); color: #14101f;
  border: 1px solid var(--accent); border-radius: var(--radius-sm);
  font-family: var(--font-sans); font-size: 15px; font-weight: 600;
  text-decoration: none; cursor: pointer;
  transition: filter var(--dur-1), color var(--dur-1), border-color var(--dur-1);
}
.btn:hover { filter: brightness(1.08); }
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.btn.ghost {
  background: transparent; color: var(--fg-2);
  border-color: var(--border-1);
}
.btn.ghost:hover { color: var(--accent); border-color: var(--accent); }

/* Os dois semânticos escrevem o texto sobre a própria cor, e não em branco:
   branco sobre o vermelho da marca dá 2,6:1, que não passa em texto
   pequeno — o mesmo cuidado que a paleta já tem com o azul do papel. */
.btn.is-danger {
  background: var(--vision-danger); border-color: var(--vision-danger);
  color: #2b0709;
}
.btn.is-approve {
  background: var(--vision-success); border-color: var(--vision-success);
  color: #06281a;
}

.field {
  width: 100%;
  padding: 11px 13px;
  background: var(--bg-0); color: var(--fg-1);
  border: 1px solid var(--border-1); border-radius: var(--radius-sm);
  font-family: var(--font-sans); font-size: 15px;
  transition: border-color var(--dur-1);
}
.field:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(169,147,255,.16);
}
select.field { cursor: pointer; }
textarea.field { resize: vertical; line-height: 1.55; }


/* ============================================================
   EMPRESAS — avatar, semáforo, ficha e formulário
   ============================================================ */

/* ── Avatar ──────────────────────────────────── */
.company-avatar {
  flex: none;
  width: 48px; height: 48px;
  border-radius: var(--radius-pill);
  object-fit: cover;
  background: var(--surface-overlay);
  border: 1px solid var(--border-1);
  display: grid; place-items: center;
}
.company-avatar.is-initials {
  font-size: 0.95rem; font-weight: 700; letter-spacing: 0.02em;
  color: var(--accent);
}
.company-avatar.is-lg {
  width: 96px; height: 96px;
  font-size: 1.9rem;
}

/* ── Semáforo ────────────────────────────────── */
/* Um ponto, e não uma pílula com a palavra escrita. O estado é lido de
   relance, correndo os olhos por uma lista, e "EM DIA / EM DIA / ALERTA" em
   coluna vira texto repetido que ninguém lê palavra por palavra. Cor sozinha
   não comunica, então a palavra não some: vai no `title` e num `sr-only`.

   Um componente só para os dois semáforos da plataforma — o da empresa (em
   dia · alerta) e o do card de cronograma (pendente · reprovado). Dois
   pontos idênticos desenhados por regras separadas divergiriam no primeiro
   ajuste de tamanho. O desenho é daqui; **onde ele fica é de cada
   hospedeiro**, logo abaixo. */
.status-dot {
  /* `relative` para o anel do pulso, que é um `::after` ancorado nele. Nos
     cards a regra de posicionamento troca isto por `absolute` — as duas
     posicionam, então o anel continua preso ao ponto e não ao card. */
  position: relative;
  flex: none;
  width: 9px; height: 9px; border-radius: 50%;
  /* A cor vem por `color`, e o ponto se pinta com `currentColor`: assim o
     anel herda a mesma tinta sem cada estado precisar declará-la duas
     vezes — quatro estados viram quatro linhas, e não oito. */
  background: currentColor;
}
.status-dot.is-em-dia    { color: var(--vision-success); }
.status-dot.is-alerta    { color: var(--vision-warning); }
.status-dot.is-pendente  { color: var(--vision-warning); }
.status-dot.is-reprovado { color: var(--vision-danger); }

/* O pulso: um anel da cor do ponto que cresce e some.

   Leve de propósito, e a leveza está em quatro escolhas. A opacidade sai de
   0,35 e não de 1 — é um halo, não um segundo ponto. O anel termina aos 70%
   do ciclo, e os 30% restantes são pausa: o ponto respira em vez de latejar
   sem parar. A expansão é `ease-out` da CSS, e **não** o `--ease-out` da
   plataforma: aquela curva é de transição de interface, e num anel de 2,6s
   ela entrega tudo nos primeiros 0,4s e deixa o resto do ciclo vazio — o que
   se vê é um piscar, que chama mais atenção do que a pulsação que se quis.
   E anima só `transform` e `opacity`, que o compositor resolve sem
   recalcular layout: numa lista de trinta empresas são trinta anéis, e
   qualquer propriedade que force reflow apareceria como travada na rolagem.

   `pointer-events: none` porque o anel passa por cima da borda do card: sem
   isto ele roubaria o hover da linha nos pixels que cobre. */
.status-dot::after {
  content: "";
  position: absolute; inset: 0;
  border-radius: 50%;
  background: currentColor;
  pointer-events: none;
  animation: status-pulse 2.6s ease-out infinite;
}

@keyframes status-pulse {
  0%   { opacity: 0.35; transform: scale(1); }
  70%  { opacity: 0;    transform: scale(2.6); }
  100% { opacity: 0;    transform: scale(2.6); }
}

/* Quem pediu menos movimento no sistema não recebe nenhum: o ponto continua
   dizendo o estado pela cor, que é o que ele veio dizer — o pulso só chama
   atenção para ele. */
@media (prefers-reduced-motion: reduce) {
  .status-dot::after { animation: none; }
}

/* Na linha da lista, o ponto vai para o canto superior direito. Absoluto
   porque ele não pode entrar na conta da grade da linha: dentro do fluxo,
   empurraria nome e resumo para ganhar um espaço que ele não precisa ocupar.
   Na barra lateral ele fica no fluxo mesmo, fechando a linha da empresa —
   ali não há canto sobrando. */
.record-row.is-company { position: relative; }
.record-row.is-company > .status-dot {
  position: absolute;
  top: var(--space-4); right: var(--space-4);
}

/* Na ficha o canto superior direito já é do botão Editar, então o ponto
   acompanha o nome da empresa — no fluxo, que é o que a base já faz. Um
   degrau maior porque ali ele divide a linha com um título de 2,6rem, e no
   tamanho da lista pareceria sujeira na tela. */
.company-header-top .status-dot { width: 11px; height: 11px; }

/* ── Ficha da empresa ────────────────────────── */
.company-page {
  position: relative;
  z-index: 1;
  flex: 1;
  width: 100%;
  max-width: 1120px;
  margin: 0 auto;
  padding: var(--space-6) var(--space-6) var(--space-9, 96px);
}

.back-link {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 0.85rem; font-weight: 600;
  color: var(--fg-3); text-decoration: none;
  margin-bottom: var(--space-5);
  transition: color var(--dur-1);
}
.back-link:hover { color: var(--accent); }
.back-link svg { width: 15px; height: 15px; }

.company-header {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: var(--space-5);
  background: var(--surface-card);
  border: 1px solid var(--border-1);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  margin-bottom: var(--space-7);
}

.company-header-body { flex: 1; min-width: 0; }

.company-header-top {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: var(--space-3);
  /* Espaço para o botão Editar, que é absoluto no canto. */
  padding-right: 128px;
  margin-bottom: var(--space-2);
}
.company-header-top h1 {
  font-family: var(--font-display);
  font-size: clamp(1.9rem, 4vw, 2.6rem);
  font-weight: 400;
  line-height: 1.1;
  letter-spacing: -0.02em;
}

.company-summary {
  font-size: 1.02rem;
  color: var(--fg-2);
  line-height: 1.5;
  margin-bottom: var(--space-5);
}

.company-meta {
  display: flex; flex-wrap: wrap;
  gap: var(--space-6);
  padding: var(--space-4) 0;
  border-top: 1px solid var(--border-1);
  border-bottom: 1px solid var(--border-1);
}
.company-meta dt {
  font-size: 0.68rem; font-weight: 600;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--fg-3);
  margin-bottom: 3px;
}
.company-meta dd { font-size: 0.98rem; color: var(--fg-1); }

.company-description {
  margin-top: var(--space-5);
  font-size: 0.96rem; color: var(--fg-2); line-height: 1.65;
}
.company-description p + p { margin-top: var(--space-3); }

/* Canto superior direito da seção que mostra as informações da empresa. */
.company-edit { position: absolute; top: var(--space-5); right: var(--space-5); }

/* ── Anexos ──────────────────────────────────── */
/* A lista mora dentro do cartão de informações da empresa. Por isso a
   linha do anexo não usa `--surface-card`, que é o fundo do cartão: um
   retângulo da cor do que está atrás dele não aparece. O par overlay /
   overlay-strong dá o mesmo degrau de contraste em tema claro e escuro. */
.company-attachments { margin-top: var(--space-5); }
.company-attachments h2 {
  font-size: 0.68rem; font-weight: 600;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--fg-3);
  margin-bottom: var(--space-3);
}
.company-attachments-empty { font-size: 0.92rem; color: var(--fg-3); line-height: 1.55; }
.company-attachments-empty strong { color: var(--fg-2); font-weight: 600; }

.attachment-list { list-style: none; display: grid; gap: var(--space-2); }
.attachment-list a {
  display: flex; align-items: center; gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
  background: var(--surface-overlay);
  border: 1px solid var(--border-1);
  border-radius: var(--radius-sm);
  text-decoration: none; color: inherit;
  transition: border-color var(--dur-1), background var(--dur-1);
}
.attachment-list a:hover {
  border-color: var(--accent);
  background: var(--surface-overlay-strong);
}
/* Três degraus: o cartão, a linha do anexo em cima dele e o ícone em
   cima da linha. Sem o terceiro, o ícone se dissolveria na própria linha. */
.attachment-icon {
  flex: none;
  width: 34px; height: 34px;
  border-radius: var(--radius-sm);
  display: grid; place-items: center;
  background: var(--surface-overlay-strong);
  color: var(--accent);
}
.attachment-icon svg { width: 18px; height: 18px; }

.attachment-name {
  flex: 1; min-width: 0;
  font-size: 0.92rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.attachment-size { flex: none; font-size: 0.8rem; color: var(--fg-3); }

/* ── Formulário de empresa ───────────────────── */
/* A coluna acompanha a largura do cartão (680px + o padding lateral da
   página), para que o formulário e o link de voltar fiquem centralizados
   na tela em vez de encostados à esquerda da grade de 1120px. */
.company-page.form-page { max-width: 744px; }
.form-page .form-card { margin-inline: auto; }

.form-card {
  max-width: 680px;
  background: var(--surface-card);
  border: 1px solid var(--border-1);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
}
.form-card h1 {
  font-family: var(--font-display);
  font-size: 1.9rem; font-weight: 400;
  margin-bottom: var(--space-5);
}

.form-row { margin-bottom: var(--space-5); }
/* `>` de propósito: o rótulo do campo é caixa-alta, mas os rótulos de
   dentro (cada checkbox de anexo) são texto normal. */
.form-row > label {
  display: block;
  font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--fg-2); margin-bottom: 7px;
}
.form-row .field,
.form-row input[type="file"] {
  width: 100%;
  padding: 11px 13px;
  background: var(--bg-0); color: var(--fg-1);
  border: 1px solid var(--border-1); border-radius: var(--radius-sm);
  font-family: var(--font-sans); font-size: 15px;
  transition: border-color var(--dur-1);
}
.form-row textarea.field { resize: vertical; line-height: 1.55; }
.form-row .field:focus,
.form-row input[type="file"]:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(169,147,255,.16);
}
.form-row.has-error .field,
.form-row.has-error input[type="file"] { border-color: var(--vision-danger); }

.form-help { display: block; margin-top: 6px; font-size: 13px; color: var(--fg-3); }

.photo-preview {
  display: flex; align-items: center; gap: var(--space-3);
  margin-bottom: var(--space-3);
  font-size: 13px; color: var(--fg-3);
}

/* Lista de remoção de anexos: uma caixa por anexo existente. O Django
   renderiza cada opção num <div> próprio dentro de um <div> externo. */
.attachment-remove {
  display: grid; gap: 4px;
  padding: var(--space-3) var(--space-4);
  background: var(--bg-0);
  border: 1px solid var(--border-1); border-radius: var(--radius-sm);
}
.attachment-remove label {
  display: flex; align-items: center; gap: 9px;
  font-size: 14px; letter-spacing: 0; text-transform: none;
  color: var(--fg-2); margin: 0; cursor: pointer;
}
.attachment-remove label:hover { color: var(--fg-1); }
.attachment-remove input[type="checkbox"] {
  accent-color: var(--accent); width: 15px; height: 15px; cursor: pointer;
}

.form-actions {
  display: flex; justify-content: flex-end; gap: var(--space-3);
  margin-top: var(--space-6);
}
.form-actions .btn {
  width: auto; padding: 11px var(--space-5); margin: 0;
  background: var(--accent); color: #14101f;
  border: 1px solid var(--accent); border-radius: var(--radius-sm);
  font-family: var(--font-sans); font-size: 15px; font-weight: 600;
  text-decoration: none; cursor: pointer;
  transition: filter var(--dur-1);
}
.form-actions .btn:hover { filter: brightness(1.08); }
.form-actions .btn.ghost {
  background: transparent; color: var(--fg-2);
  border-color: var(--border-1);
}
.form-actions .btn.ghost:hover { color: var(--accent); border-color: var(--accent); }

@media (max-width: 640px) {
  .company-page { padding: var(--space-5) var(--space-5) var(--space-8); }
  .company-header { flex-direction: column; align-items: center; text-align: center; }
  .company-header-top { justify-content: center; padding-right: 0; }
  .company-meta { justify-content: center; }
  /* O cartão centraliza no celular, mas uma lista de arquivos alinhada
     ao centro fica com cada nome começando num ponto diferente. */
  .company-attachments { text-align: left; }
  .company-edit { top: var(--space-4); right: var(--space-4); }
}

/* Divisor de seção dentro do formulário — separa os dados da empresa dos
   dados de acesso, que são coisas diferentes na mesma tela. */
.form-section {
  margin: var(--space-6) 0 var(--space-5);
  padding-top: var(--space-5);
  border-top: 1px solid var(--border-1);
}
.form-section span {
  display: block;
  font-size: 0.72rem; font-weight: 600;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 6px;
}
.form-section p { font-size: 13px; color: var(--fg-3); line-height: 1.5; }


/* ============================================================
   LISTAS DE GESTÃO — Equipe e Clientes, e as confirmações
   ============================================================
   `.record-*` e não `.team-*`: as duas telas de gestão têm o mesmo
   desenho de linha, e o nome não pode dizer só metade.
   ============================================================ */
/* Título à esquerda, ação principal à direita — o mesmo canto onde a ficha
   da empresa põe o lápis. */
.page-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-5);
  margin-bottom: var(--space-7);
}
.page-head-text { min-width: 0; }
.page-head h1 {
  font-family: var(--font-display);
  font-size: clamp(1.9rem, 4vw, 2.6rem);
  font-weight: 400; line-height: 1.1; letter-spacing: -0.02em;
  margin-bottom: var(--space-3);
}
.page-head p { font-size: 1rem; color: var(--fg-3); line-height: 1.55; max-width: 62ch; }

/* As duas listas de gestão respiram mais do que as fichas: são tabelas de
   consulta, e apertar as colunas obriga e-mail e CNPJ a quebrar no meio. */
.record-page { max-width: 1320px; }

.record-list { list-style: none; display: grid; gap: var(--space-3); }

.record-row {
  display: grid;
  /* Larguras fixas, e não `auto`: cada linha é um grid próprio, e com
     colunas elásticas os rótulos dançavam de uma linha para a outra. A
     última é fixa porque a linha de quem está logado troca "Excluir" por
     "Você", que é mais estreito — e isso empurrava a linha inteira. */
  grid-template-columns: auto minmax(210px, 1fr) minmax(330px, 1.5fr) 190px;
  align-items: center;
  gap: var(--space-4) var(--space-5);
  padding: var(--space-4) var(--space-5);
  background: var(--surface-card);
  border: 1px solid var(--border-1);
  border-radius: var(--radius-md);
}
/* Conta desativada continua listada: sumir com ela esconderia que existe e
   que o e-mail segue ocupado. Mas não pode parecer ativa. */
.record-row.is-inactive { opacity: 0.6; }

.record-identity { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.record-identity strong { font-size: 0.98rem; font-weight: 600; }
.record-sub {
  font-size: 0.84rem; color: var(--fg-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.record-tags { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 3px; }
.tag.super { background: rgba(242,181,68,0.16); color: var(--vision-warning); }
.tag.danger { background: rgba(255,90,95,0.14); color: var(--vision-danger); }

/* Grade de 4, não flex: é o que faz Cargo/Empresa/Desde/Último acesso
   caírem na mesma coluna em todas as linhas. */
.record-facts {
  display: grid;
  /* Desiguais: cargo é texto livre e precisa de folga; as datas têm largura
     conhecida e não ganham nada com mais espaço. */
  grid-template-columns: minmax(0, 1fr) 92px 126px;
  gap: var(--space-4);
}
/* Quebra linha em vez de cortar: estas telas existem para mostrar as
   informações, e esconder metade de um cargo atrás de "…" desfaz o motivo
   delas. */
.record-facts dd { overflow-wrap: anywhere; line-height: 1.35; }

/* A lista de Clientes mostra outros dados, com outras larguras naturais:
   CNPJ e contagem de anexos têm tamanho conhecido, e o e-mail precisa da
   folga que sobra para não quebrar no meio do domínio. */
.record-row.is-company .record-facts {
  grid-template-columns: 148px minmax(0, 1fr) 62px 126px;
}

/* A linha da empresa é um link inteiro: sem coluna de ações, com a seta no
   lugar dela. */
.record-row.is-company {
  grid-template-columns: auto minmax(220px, 1fr) minmax(430px, 1.6fr) 20px;
  color: inherit;
  text-decoration: none;
  transition: transform var(--dur-2) var(--ease-out),
              border-color var(--dur-2),
              box-shadow var(--dur-2);
}
.record-row.is-company:hover {
  transform: translateY(-2px);
  border-color: var(--accent);
  box-shadow: var(--shadow-2);
}
.record-row.is-company:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: var(--shadow-focus);
}

.record-go {
  width: 18px; height: 18px;
  color: var(--fg-4);
  transition: color var(--dur-2), transform var(--dur-2);
}
.record-row.is-company:hover .record-go {
  color: var(--accent);
  transform: translateX(3px);
}
.record-facts dt {
  font-size: 0.62rem; font-weight: 600;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--fg-4); margin-bottom: 2px;
}
.record-facts dd { font-size: 0.86rem; color: var(--fg-2); }
.record-facts a { color: var(--accent); }

.record-actions { display: flex; justify-content: flex-end; gap: var(--space-2); }

.btn-mini {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 12px;
  background: transparent;
  border: 1px solid var(--border-1); border-radius: var(--radius-sm);
  color: var(--fg-2); font-size: 0.82rem; font-weight: 600;
  text-decoration: none; cursor: pointer;
  transition: color var(--dur-1), border-color var(--dur-1);
}
.btn-mini:hover { color: var(--accent); border-color: var(--accent); }
.btn-mini.is-danger:hover { color: var(--vision-danger); border-color: var(--vision-danger); }
.btn-mini.is-off { opacity: 0.45; cursor: not-allowed; }
.btn-mini.is-off:hover { color: var(--fg-2); border-color: var(--border-1); }
.btn-mini svg { width: 14px; height: 14px; }

/* ── Confirmações ────────────────────────────── */
.form-lead {
  font-size: 0.95rem; color: var(--fg-3); line-height: 1.6;
  margin: calc(var(--space-5) * -1 + 4px) 0 var(--space-5);
}
.form-lead a { color: var(--accent); }

.form-card.is-danger { border-color: rgba(255,90,95,0.35); }

.form-check {
  display: flex !important; align-items: center; gap: 9px;
  font-size: 14px !important; letter-spacing: 0 !important;
  text-transform: none !important; color: var(--fg-2) !important;
  margin: 0 !important; cursor: pointer;
}
.form-check input[type="checkbox"] {
  accent-color: var(--accent); width: 15px; height: 15px; cursor: pointer;
}

/* O "de → para" de cada campo. Confirmar sem ver o que muda é um clique no
   escuro: a pessoa aprova "salvar", não a troca de papel três campos acima. */
.diff-list { list-style: none; display: grid; gap: var(--space-2); margin-bottom: var(--space-6); }
.diff-list li {
  display: grid;
  grid-template-columns: minmax(120px, auto) 1fr auto 1fr;
  align-items: center; gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  background: var(--bg-0);
  border: 1px solid var(--border-1); border-radius: var(--radius-sm);
}
.diff-label {
  font-size: 0.68rem; font-weight: 600;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--fg-3);
}
.diff-de { font-size: 0.92rem; color: var(--fg-3); text-decoration: line-through; }
.diff-seta { width: 15px; height: 15px; color: var(--accent); }
.diff-para { font-size: 0.92rem; font-weight: 600; color: var(--fg-1); }
/* A linha da senha não tem "de": o valor antigo não existe em lugar
   nenhum legível, e o novo não se mostra. */
.diff-list li.is-senha { grid-template-columns: minmax(120px, auto) 1fr; }

.confirm-subject {
  display: flex; align-items: center; gap: var(--space-4);
  padding: var(--space-4);
  background: var(--bg-0);
  border: 1px solid var(--border-1); border-radius: var(--radius-sm);
  margin-bottom: var(--space-5);
}
.confirm-subject strong { display: block; font-size: 1rem; }
.confirm-subject span { font-size: 0.86rem; color: var(--fg-3); }

.warn-list { list-style: none; display: grid; gap: var(--space-2); margin-bottom: var(--space-5); }
.warn-list li {
  position: relative; padding-left: var(--space-5);
  font-size: 0.92rem; color: var(--fg-2); line-height: 1.5;
}
.warn-list li::before {
  content: "•"; position: absolute; left: 6px; color: var(--fg-4);
}
.warn-list li.is-grave { color: var(--fg-1); }
.warn-list li.is-grave::before { content: "!"; font-weight: 700; color: var(--vision-danger); }

.form-actions .btn.is-danger {
  background: var(--vision-danger); border-color: var(--vision-danger);
  /* Mesma tinta escura da base: branco sobre este vermelho não passa de
     2,6:1, e duas telas com o mesmo botão em cores diferentes é pior. */
  color: #2b0709;
}

@media (max-width: 900px) {
  .record-row { grid-template-columns: auto minmax(0, 1fr); }
  /* A seta sai: a linha inteira já é o alvo, e ela roubaria largura de
     quem tem pouca. */
  .record-row.is-company { grid-template-columns: auto minmax(0, 1fr); }
  .record-go { display: none; }
  .record-facts, .record-actions { grid-column: 1 / -1; }
  .record-actions { justify-content: flex-start; }
  /* `.is-company` junto: as larguras fixas dela (148px de CNPJ, 126px de
     data) somam mais que a tela do celular, e a especificidade maior
     venceria esta regra sem o seletor repetido. */
  .record-facts,
  .record-row.is-company .record-facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .diff-list li { grid-template-columns: 1fr; gap: 4px; }
  .diff-seta { transform: rotate(90deg); justify-self: start; }
}

/* Ação principal de uma tela de lista. Preenchida, não contornada: é o
   que a pessoa veio fazer aqui, e disputa a atenção com uma lista inteira
   de linhas. */
.page-action {
  display: inline-flex; align-items: center; gap: 8px;
  flex: none;
  padding: 11px var(--space-5);
  background: var(--accent); color: #14101f;
  border: 1px solid var(--accent); border-radius: var(--radius-sm);
  font-size: 0.95rem; font-weight: 600; text-decoration: none;
  transition: filter var(--dur-1);
}
.page-action:hover { filter: brightness(1.08); }
.page-action svg { width: 15px; height: 15px; }

@media (max-width: 640px) {
  /* Empilha: o botão inteiro cabe na largura, e cortá-lo ao lado do
     título o deixaria só com o ícone. */
  .page-head { flex-direction: column; align-items: stretch; }
  .page-action { justify-content: center; }
}

/* ============================================================
   CRONOGRAMAS
   ============================================================ */

/* Cabeçalho de seção com ação no canto direito — o mesmo canto do "Editar"
   da ficha e do "Nova empresa" da lista. O `.section-label` continua sendo
   o rótulo com a linha; aqui ele só divide a faixa com o botão. */
.section-head {
  display: flex; align-items: center; gap: var(--space-4);
  margin-bottom: var(--space-5);
}
.section-head .section-label { flex: 1; min-width: 0; margin-bottom: 0; }

.schedule-years { display: grid; gap: var(--space-3); }

/* Um ano é um `<details>`. O triângulo nativo sai de cena — ele não
   acompanha a tipografia da plataforma e não dá para alinhar com o resto
   da linha; a seta que entra no lugar é a mesma da lista de empresas. */
.schedule-year { border: 1px solid var(--border-1); border-radius: var(--radius-md); }
.schedule-year > summary {
  display: flex; align-items: center; gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  cursor: pointer; list-style: none; user-select: none;
  border-radius: var(--radius-md);
}
.schedule-year > summary::-webkit-details-marker { display: none; }
.schedule-year > summary:hover { background: var(--surface-overlay); }
.schedule-year > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

.schedule-caret {
  flex: none; width: 15px; height: 15px; color: var(--fg-3);
  transition: transform 0.15s ease;
}
.schedule-year[open] > summary .schedule-caret { transform: rotate(90deg); }

.schedule-ano {
  font-size: 1.05rem; font-weight: 600; color: var(--fg-1);
  font-variant-numeric: tabular-nums;
}
/* A contagem fica do lado do ano, e não no fim da linha: contraído, o
   grupo precisa dizer quanta coisa esconde. */
.schedule-count { font-size: 0.82rem; color: var(--fg-3); }

.schedule-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: var(--space-3);
  padding: 0 var(--space-5) var(--space-5);
}

.schedule-card {
  /* `relative` por causa da bolinha do canto, que é posicionada por ele.
     Era `block`, e o bloco continua: o `position` não muda o fluxo. */
  position: relative;
  display: block;
  border: 1px solid var(--border-1); border-radius: var(--radius-md);
  background: var(--surface-overlay);
  padding: var(--space-4);
  text-decoration: none; color: inherit;
  transition: border-color var(--dur-1), background var(--dur-1), transform var(--dur-2) var(--ease-out);
}
.schedule-card:hover {
  border-color: var(--accent);
  background: var(--surface-overlay-strong);
  transform: translateY(-2px);
}
.schedule-card:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.schedule-card h3 {
  font-size: 1rem; font-weight: 600; color: var(--fg-1);
  margin-bottom: 6px;
}
.schedule-card p {
  font-size: 0.88rem; color: var(--fg-2); line-height: 1.5;
  /* Espaço para a bolinha na primeira linha do resumo: sem ele, um resumo
     de linha cheia passa por baixo do ponto. O título não precisa — ele é
     curto ("Outubro") e para muito antes do canto. */
  padding-right: var(--space-4);
}

/* A bolinha de alerta do mês: canto superior direito, alinhada pela mesma
   medida do padding do card — ela fica na altura do nome do mês, que é onde
   o olho já está quando corre a grade de cronogramas. O desenho e as cores
   vêm de `.status-dot`, lá em cima, junto do semáforo da empresa. */
.schedule-card > .status-dot {
  position: absolute; top: var(--space-4); right: var(--space-4);
}

/* Mês e ano dividem a linha; o resumo ocupa as duas colunas. */
.form-grid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 var(--space-4);
}
.form-grid .form-row.is-wide { grid-column: 1 / -1; }
/* A seta nativa do `select` fica: trocá-la por uma desenhada custaria
   um `appearance: none` e um background-image só para chegar perto do
   que o sistema já desenha — e sem a seta o campo some como lista. */
.form-row select.field { cursor: pointer; }

@media (max-width: 560px) {
  .section-head { flex-direction: column; align-items: stretch; }
  .form-grid { grid-template-columns: minmax(0, 1fr); }
}

/* ============================================================
   USUÁRIOS VINCULADOS A UMA EMPRESA
   ============================================================ */

/* Fecha o cartão de informações: quem atende a empresa é informação dela.
   Mesmo degrau tipográfico do rótulo de anexos, logo acima. */
.company-users { margin-top: var(--space-5); }
.company-users h2 {
  font-size: 0.68rem; font-weight: 600;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--fg-3);
  margin-bottom: var(--space-3);
}
.company-users-empty { font-size: 0.92rem; color: var(--fg-3); line-height: 1.55; }
.company-users-empty strong { color: var(--fg-2); font-weight: 600; }

/* Pílulas em linha: são nomes curtos e costumam ser poucos: uma lista
   vertical viraria uma coluna alta dentro do cartão. */
.user-pills { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; }

.user-pill {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 5px 12px 5px 5px;
  border: 1px solid var(--border-1);
  border-radius: 999px;
  background: var(--surface-overlay);
  font-size: 0.86rem; font-family: inherit; color: var(--fg-1);
  text-decoration: none; cursor: pointer;
  transition: border-color var(--dur-1), background var(--dur-1);
}
button.user-pill:hover { border-color: var(--accent); background: var(--surface-overlay-strong); }
.user-pill:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* Conta desativada continua na lista: sumir com ela esconderia que o
   vínculo existe e que aquele e-mail segue ocupado. */
.user-pill.is-off { opacity: 0.55; }

.user-pill-avatar {
  flex: none;
  width: 24px; height: 24px;
  border-radius: 50%;
  display: grid; place-items: center;
  background: var(--surface-overlay-strong);
  font-size: 0.62rem; font-weight: 700; letter-spacing: 0.04em;
  color: var(--fg-2);
}
.user-pill-name { white-space: nowrap; }

/* As ações saíram da pílula e foram para o painel: um botão de desvincular
   dentro de um botão que abre o painel é HTML inválido, e a pílula ficava
   com dois alvos de toque de 16px colados um no outro. */

/* A ação entra como mais uma pílula, contornada em vez de preenchida: é
   irmã das que estão ao lado, não a ação principal da tela. */
.user-pill.is-add {
  padding: 5px 14px;
  border-style: dashed;
  background: none;
  color: var(--accent);
  font-weight: 600;
}
.user-pill.is-add:hover { background: var(--surface-overlay); }
.user-pill.is-add svg { width: 13px; height: 13px; }

/* ── Vincular usuário ────────────────────────── */
/* Os dois modos ficam visíveis sem JavaScript, e o servidor decide pelo
   `mode`; o script só esconde o bloco que não vale. */
.mode-choice { display: grid; gap: var(--space-2); }
.mode-choice label {
  display: flex; align-items: center; gap: 8px;
  font-size: 0.92rem; color: var(--fg-2); cursor: pointer;
}
.mode-choice input[type="radio"] { accent-color: var(--accent); width: 15px; height: 15px; }

.mode-block { border: 0; padding: 0; margin: 0; }
.mode-block[hidden] { display: none; }

/* Só para leitor de tela: o × da pílula tem ícone e `title`, mas quem não
   vê o ícone precisa do texto. */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}


/* ── Ficha de um usuário vinculado ───────────── */
/* Popover nativo: o navegador cuida de abrir, do Esc, do clique fora e de
   subir acima do resto. O padrão do `[popover]` já é centralizado na tela,
   o que num painel curto funciona igual no desktop e no celular.

   `display: none` como base, e visível só em `:popover-open`: num navegador
   sem suporte a Popover o seletor é inválido, a regra cai inteira e o painel
   fica escondido — o clique não faz nada, em vez de a página abrir com todos
   os painéis empilhados à vista. */
.user-card { display: none; }
.user-card:popover-open {
  display: grid;
  /* O navegador centraliza o `[popover]` com `inset: 0` e `margin: auto` —
     mas o reset do topo deste arquivo zera a margem de tudo, e estilo de
     autor vence o do navegador: sem repetir as três linhas aqui, o painel
     encosta no canto superior esquerdo da tela. */
  position: fixed; inset: 0; margin: auto;
  gap: var(--space-4);
  width: min(420px, calc(100vw - 2 * var(--space-5)));
  padding: var(--space-5);
  border: 1px solid var(--border-1);
  border-radius: var(--radius-lg);
  background: var(--surface-card);
  color: var(--fg-1);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.35);
}
.user-card::backdrop { background: rgba(0, 0, 0, 0.45); }

.user-card-head { display: flex; align-items: flex-start; gap: var(--space-4); }
.user-card-identity { flex: 1; min-width: 0; display: grid; gap: 3px; }
.user-card-identity strong { font-size: 1.02rem; font-weight: 600; }
.user-card-identity span { font-size: 0.86rem; color: var(--fg-3); overflow-wrap: anywhere; }

.user-card-close {
  flex: none;
  display: grid; place-items: center;
  width: 26px; height: 26px;
  padding: 0; border: 0; border-radius: 50%;
  background: none; color: var(--fg-3);
  cursor: pointer;
  transition: color var(--dur-1), background var(--dur-1);
}
.user-card-close:hover { color: var(--fg-1); background: var(--surface-overlay); }
.user-card-close svg { width: 13px; height: 13px; }

/* Duas colunas: são quatro dados curtos, e um por linha faria o painel
   crescer mais do que o conteúdo pede. */
.user-card-meta {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-4);
  padding: var(--space-4) 0;
  border-top: 1px solid var(--border-1);
  border-bottom: 1px solid var(--border-1);
}
.user-card-meta dt {
  font-size: 0.66rem; font-weight: 600;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--fg-3);
  margin-bottom: 3px;
}
.user-card-meta dd { font-size: 0.88rem; color: var(--fg-1); overflow-wrap: anywhere; }

.user-card-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.user-card-actions .btn-mini { text-decoration: none; }

@media (max-width: 560px) {
  .user-card-meta { grid-template-columns: minmax(0, 1fr); gap: var(--space-3); }
}


/* ============================================================
   CRONOGRAMA — a tela de um mês
   ============================================================ */

/* Os contadores logo abaixo são a continuação do cabeçalho, e não a
   próxima seção: o respiro entre os dois é menor que o da ficha. */
.schedule-page .company-header { align-items: center; margin-bottom: var(--space-5); }

.schedule-header-top { display: grid; gap: 4px; margin-bottom: var(--space-3); }
/* A empresa vira sobrescrito: quem chega aqui já sabe de quem é o
   cronograma — o que a tela precisa dizer num relance é *qual mês*. */
.schedule-eyebrow {
  font-size: 0.68rem; font-weight: 600;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--fg-3);
}
.schedule-header h1 {
  font-family: var(--font-display);
  font-size: clamp(1.9rem, 4vw, 2.6rem); font-weight: 400;
  line-height: 1.05; letter-spacing: -0.01em;
}
/* O ano acompanha o mês no mesmo degrau, em peso menor: é a desambiguação,
   não o título. */
.schedule-header h1 span { color: var(--fg-3); font-variant-numeric: tabular-nums; }

/* ── Contadores ──────────────────────────────── */
/* `auto-fit` com mínimo de 150px: quatro em linha no desktop, dois e dois
   no celular, sem media query. */
.schedule-stats {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--space-3);
  margin-bottom: var(--space-6);
}
.schedule-stats .stat {
  border: 1px solid var(--border-1); border-radius: var(--radius-md);
  background: var(--surface-card);
  padding: var(--space-4) var(--space-5);
}
.schedule-stats dt {
  font-size: 0.68rem; font-weight: 600;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--fg-3);
  margin-bottom: 6px;
}
.schedule-stats dd {
  font-family: var(--font-display);
  font-size: 2rem; line-height: 1;
  color: var(--fg-1);
  font-variant-numeric: tabular-nums;
}
/* Os três estados que pedem ação de alguém ganham cor; o total fica neutro,
   porque é a moldura dos outros — colorir os quatro seria não destacar
   nenhum. As cores são as mesmas dos selos sobre as artes: quem lê "12
   aguardando" aqui em cima procura os selos dessa cor na grade. */
.schedule-stats .stat.is-aguardando dd { color: var(--accent); }
.schedule-stats .stat.is-aprovado dd  { color: var(--vision-success); }
.schedule-stats .stat.is-reprovado dd { color: var(--vision-danger); }

/* ── O feed ──────────────────────────────────── */
/* Três colunas fixas, inclusive no celular: a grade existe para prever o
   feed, e em duas colunas ela mostraria um mês que não é o que vai ao ar. */
.post-feed {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-3);
}
@media (max-width: 560px) { .post-feed { gap: 5px; } }

/* O feed de baixo é o mesmo feed, dessaturado e um pouco apagado: as peças
   estão ali para consulta, não para compor o mês, e no mesmo viço
   disputariam o olho com a grade que interessa. Volta ao normal no hover e
   no foco — quem foi até lá quer ver a arte como ela é. */
.post-feed.is-cancelados .post-tile {
  filter: grayscale(0.7); opacity: 0.62;
  transition: filter var(--dur-2), opacity var(--dur-2),
              border-color var(--dur-1), transform var(--dur-2) var(--ease-out),
              box-shadow var(--dur-2);
}
.post-feed.is-cancelados .post-tile:hover,
.post-feed.is-cancelados .post-tile:focus-visible {
  filter: none; opacity: 1;
}

/* O cabeçalho do feed de baixo não tem ação no canto — tem a contagem, que
   é a pergunta que se faz dele: quantas peças do mês foram descartadas. */
.section-head.is-cancelados { margin-top: var(--space-7); }
.section-head .section-count {
  /* `align-self` além do `flex: none`: no celular o cabeçalho vira coluna
     com `align-items: stretch`, e sem isto a pílula de um dígito atravessa
     a tela inteira. */
  flex: none; align-self: flex-start;
  padding: 3px 10px; border-radius: var(--radius-pill);
  border: 1px solid var(--border-1);
  font-size: 0.72rem; font-weight: 700;
  color: var(--fg-3); font-variant-numeric: tabular-nums;
}

.post-tile {
  position: relative;
  display: block; width: 100%;
  padding: 0; border: 1px solid var(--border-1); border-radius: var(--radius-md);
  background: none; overflow: hidden; cursor: pointer;
  transition: border-color var(--dur-1), transform var(--dur-2) var(--ease-out),
              box-shadow var(--dur-2);
}
.post-tile:hover {
  border-color: var(--accent);
  transform: translateY(-3px);
  box-shadow: var(--shadow-3);
}
.post-tile:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* A proporção é do card, e não da imagem: com ela a grade tem altura antes
   de a primeira arte carregar, e nada pula de lugar quando elas chegam. */
.post-art { display: block; aspect-ratio: 1080 / 1350; background: var(--surface-overlay); }
.post-art > * { display: block; width: 100%; height: 100%; }
.post-art img { object-fit: cover; }

/* Marcador de post sem arte. `--hue` chega pelo `style` do elemento e é a
   única coisa que muda de um para o outro; o resto é o mesmo desenho. */
.post-art-blank {
  --blank-bg:   hsl(var(--hue) 42% 91%);
  --blank-ink:  hsl(var(--hue) 48% 44%);
  --blank-sub:  hsl(var(--hue) 26% 58%);
  --blank-glow: hsl(var(--hue) 68% 62%);
}
:root.dark .post-art-blank,
[data-theme="dark"] .post-art-blank {
  --blank-bg:  hsl(var(--hue) 30% 14%);
  --blank-ink: hsl(var(--hue) 72% 82%);
  --blank-sub: hsl(var(--hue) 34% 62%);
}
.post-art-blank .blank-bg { fill: var(--blank-bg); }
.post-art-blank .blank-glow { fill: var(--blank-glow); opacity: 0.26; }
.post-art-blank .blank-glow.is-soft { opacity: 0.14; }
.post-art-blank .blank-number {
  fill: var(--blank-ink);
  font-family: var(--font-display); font-size: 300px;
}
.post-art-blank .blank-caption {
  fill: var(--blank-sub);
  font-family: var(--font-sans); font-size: 58px;
  font-weight: 600; letter-spacing: 6px;
}

/* ── Selo de estado ──────────────────────────── */
/* Sobre a arte, canto inferior: é o que se procura correndo os olhos pela
   grade — quais ainda faltam aprovar. */
.post-flag {
  position: absolute; left: 8px; bottom: 8px;
  padding: 4px 10px; border-radius: var(--radius-pill);
  font-size: 0.62rem; font-weight: 700;
  letter-spacing: 0.08em; text-transform: uppercase;
  /* O selo fica sobre uma imagem qualquer, que pode ser clara ou escura:
     o contraste tem de vir do próprio selo, não do que está atrás. */
  background: rgba(10, 10, 10, 0.72); color: var(--vision-paper);
  backdrop-filter: blur(6px);
}
/* Pendente fica com o fundo neutro herdado acima: é o estado de quem ainda
   está montando, e não tem recado para dar a ninguém. Os outros quatro se
   distinguem à distância de um feed inteiro — aguardando no roxo da marca,
   aprovado no verde, reprovado no vermelho, cancelado apagado. */
.post-flag.is-aguardando { background: rgba(58, 38, 132, 0.88); color: #ddd2ff; }
.post-flag.is-aprovado  { background: rgba(21, 90, 58, 0.86);  color: #b9f2d4; }
.post-flag.is-reprovado { background: rgba(120, 26, 30, 0.86); color: #ffd2d3; }
/* O cancelado não disputa atenção: ele já desceu para o feed de baixo, e
   o selo só confirma por que a peça está lá. */
.post-flag.is-cancelado { background: rgba(10, 10, 10, 0.78); color: #c4c1cc; }

/* Dentro do painel o selo é texto entre textos, e não uma etiqueta colada
   numa foto: sai do canto e volta ao fluxo. */
.post-flag.is-inline { position: static; display: inline-block; }

/* Numa coluna de três — que é o que a grade é em qualquer largura —, o card
   do celular tem pouco mais de cem pixels, e o selo é maior que ele: o
   `overflow: hidden` do card corta o fim da palavra, e o estado vira
   "REPROVAD". Diminuir o degrau é o que cabe: o selo continua legível, e a
   alternativa seria abreviar o nome dos estados, que é justamente o que o
   selo existe para dizer. Só na grade — no painel sobra linha. */
@media (max-width: 400px) {
  .post-tile .post-flag {
    padding: 3px 7px;
    font-size: 0.55rem; letter-spacing: 0.04em;
  }
}

/* A data prevista, no canto de cima. Mesma mecânica do selo — fundo próprio
   porque o que está atrás é uma arte qualquer —, em peso menor: o selo diz
   se a peça está de pé, a data só diz quando ela sai. */
.post-date {
  position: absolute; left: 8px; top: 8px;
  padding: 4px 9px; border-radius: var(--radius-pill);
  font-size: 0.68rem; font-weight: 600;
  background: rgba(10, 10, 10, 0.6); color: var(--vision-paper);
  backdrop-filter: blur(6px);
  white-space: nowrap;
}

/* O ícone de ampliar só aparece no hover: na grade parada ele competiria
   com a arte, que é o que a tela veio mostrar. */
.post-tile-open {
  position: absolute; top: 8px; right: 8px;
  display: grid; place-items: center;
  width: 28px; height: 28px; border-radius: 50%;
  background: rgba(10, 10, 10, 0.6); color: var(--vision-paper);
  opacity: 0; transition: opacity var(--dur-2);
}
.post-tile-open svg { width: 13px; height: 13px; }
.post-tile:hover .post-tile-open,
.post-tile:focus-visible .post-tile-open { opacity: 1; }

/* ── O popup do post ─────────────────────────── */
/* Mesma escolha da ficha do usuário vinculado: Popover API nativa, e
   `display: none` como base — num navegador sem suporte o seletor
   `:popover-open` é inválido, a regra cai inteira e o painel fica
   escondido, em vez de a página abrir com todos empilhados à vista. */
.post-card { display: none; }
.post-card:popover-open {
  display: grid;
  /* Centralizado à mão pelo mesmo motivo da ficha do usuário: o reset do
     topo deste arquivo zera o `margin: auto` que o navegador dá ao
     `[popover]`, e o painel iria para o canto. */
  position: fixed; inset: 0; margin: auto;
  gap: var(--space-4);
  width: min(560px, calc(100vw - 2 * var(--space-4)));
  max-height: min(92vh, 1000px);
  overflow: auto;
  overscroll-behavior: contain;
  padding: var(--space-5);
  border: 1px solid var(--border-1);
  border-radius: var(--radius-lg);
  background: var(--surface-card);
  color: var(--fg-1);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.35);
}
.post-card::backdrop { background: rgba(0, 0, 0, 0.6); }

/* Chegando pela âncora do calendário, quem abre o painel é o `showPopover()`
   — e o foco vai para ele, o que é certo: quem veio de outra tela precisa do
   teclado dentro do painel, e não atrás dele. O que não pode ficar é o anel
   azul do navegador, a única coisa na tela que não sai do design system.
   Aberto pelo card o foco fica no botão, e este anel não aparece. */
.post-card:popover-open:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* O vão é curto porque o que ele separa é o punhado de ícones do canto —
   baixar, editar, excluir e fechar formam um grupo, e 16px entre eles os
   leria como quatro ações soltas. A distância até o texto não sai daqui: a
   identidade é `flex: 1` e empurra o grupo para a borda sozinha. */
.post-card-head { display: flex; align-items: flex-start; gap: var(--space-2); }
.post-card-identity { flex: 1; min-width: 0; display: grid; gap: 3px; }
.post-card-identity strong { font-size: 1.02rem; font-weight: 600; }
.post-card-identity span { font-size: 0.86rem; color: var(--fg-3); }

.post-card-fields { display: grid; gap: var(--space-4); }
.post-field h3 {
  font-size: 0.68rem; font-weight: 600;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--fg-3);
  margin-bottom: 6px;
}
.post-field p { font-size: 0.92rem; color: var(--fg-1); line-height: 1.6; }

/* Observações ganham moldura: é recado sobre a peça — o que foi pedido, o
   que mudou —, e não a peça. Sem a borda, ele se lê como continuação da
   copy, que é o texto que vai ao ar. */
.post-field.is-boxed {
  padding: var(--space-4);
  border: 1px solid var(--border-1); border-radius: var(--radius-md);
  background: var(--surface-overlay);
}
.post-field p + p { margin-top: var(--space-3); }
.post-field-empty { color: var(--fg-3); font-style: italic; }

/* O link do post, no mesmo desenho das linhas de anexo da ficha: ícone,
   nome e a caixa inteira como alvo do clique. */
.post-link {
  display: flex; align-items: center; gap: var(--space-3);
  padding: 10px var(--space-3);
  border: 1px solid var(--border-1); border-radius: var(--radius-sm);
  background: var(--surface-overlay);
  color: var(--fg-1); text-decoration: none;
  font-size: 0.9rem;
  transition: border-color var(--dur-1), background var(--dur-1), color var(--dur-1);
}
.post-link:hover {
  border-color: var(--accent); color: var(--accent);
  background: var(--surface-overlay-strong);
}
.post-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.post-link svg { flex: none; width: 17px; height: 17px; color: var(--accent); }
/* Uma linha só, cortada com reticências: um link de rastreamento tem duas
   centenas de caracteres e quebraria o painel em quatro linhas. */
.post-link-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }


/* ============================================================
   POST — carrossel, ações do popup e formulário
   ============================================================ */

/* O contador de artes, no canto oposto à data: é o sinal do Instagram —
   diz que há mais coisa atrás da capa antes de alguém abrir para ver. */
.post-stack {
  position: absolute; right: 8px; top: 8px;
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 9px; border-radius: var(--radius-pill);
  font-size: 0.68rem; font-weight: 700;
  background: rgba(10, 10, 10, 0.6); color: var(--vision-paper);
  backdrop-filter: blur(6px);
}
.post-stack svg { width: 12px; height: 12px; }
/* Com contador no canto, o ícone de ampliar desce para não empilhar. */
.post-tile:has(.post-stack) .post-tile-open { top: 40px; }

/* ── Carrossel ───────────────────────────────── */
/* Faixa com `scroll-snap`, sem uma linha de JavaScript: arrastar é o gesto
   que o celular já tem, e a faixa é focável para o teclado rolar. */
.post-carousel {
  display: flex;
  gap: var(--space-3);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  overscroll-behavior-x: contain;
  border-radius: var(--radius-md);
}
.post-carousel:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* Altura fixa e arte `contain`: as duas proporções do feed convivem na
   mesma faixa sem uma esticar a outra, e a peça de story aparece inteira —
   é aqui que ela é conferida. A altura não varia de um slide para o outro
   de propósito: com `scroll-snap`, uma faixa que muda de altura a cada
   arraste empurraria o texto de baixo para cima e para baixo.

   A altura é a conta que faz a peça caber inteira **sem rolar**: o painel
   vai até 92vh, o cabeçalho e os respiros comem uns 82px, e 64vh deixa a
   arte de story — a mais alta que entra — terminar acima da dobra do painel
   em qualquer tela a partir de ~300px de altura. Os textos ficam abaixo, que
   é onde se rola para lê-los.

   `flex`, e não `grid`: é o que faz o `max-height: 100%` da arte ter contra
   o que resolver. Numa grade, a porcentagem mede a *linha* — que é `auto`, e
   portanto medida pela própria arte: a conta se morde e o navegador a
   descarta, e a arte de story voltava a ser medida só pela largura, saindo
   mais alta do que a faixa e pedindo rolagem justamente para se ver
   inteira. O contêiner flex tem altura declarada, e a porcentagem mede ela. */
.post-slide {
  /* Declarada uma vez e reaproveitada pelo marcador, abaixo: as duas medidas
     precisam ser a mesma, e duas cópias do mesmo `min()` não ficam iguais
     por muito tempo. */
  --slide-h: min(64vh, 720px);

  flex: 0 0 100%;
  scroll-snap-align: center;
  display: flex; align-items: center; justify-content: center;
  height: var(--slide-h);
}
.post-slide img {
  max-width: 100%; max-height: 100%;
  object-fit: contain;
  border-radius: var(--radius-md);
}
/* O marcador de post sem arte ocupa a faixa como uma arte 4:5 ocuparia.
   Ele é um `<span>` desenhado, e não uma imagem: não há `object-fit` para
   encaixá-lo, então quem faz o papel é a largura. Ela é a menor entre a da
   faixa e a que um 4:5 teria na altura cheia — e como a altura sai daí pelo
   `aspect-ratio`, ela nunca passa da faixa, nem na tela estreita onde é a
   largura que manda. Medir pela altura e cortar a largura no `max-width`
   deformaria o desenho: o `slice` do SVG o recortaria em vez de encaixá-lo. */
.post-slide.is-blank .post-art {
  width: min(100%, calc(var(--slide-h) * 1080 / 1350));
  height: auto;
  border-radius: var(--radius-md); overflow: hidden;
}
.post-carousel-hint {
  margin-top: calc(-1 * var(--space-2));
  font-size: 0.78rem; color: var(--fg-3); line-height: 1.5;
}

/* ── Ações do popup ──────────────────────────── */
/* Lápis e lixeira flutuam junto do fechar, no canto de cima: são ações
   sobre a peça aberta, e ficam onde a mão já está. */
.post-card-action {
  flex: none;
  display: grid; place-items: center;
  width: 26px; height: 26px;
  border-radius: 50%;
  color: var(--fg-3);
  transition: color var(--dur-1), background var(--dur-1);
}
.post-card-action:hover { color: var(--fg-1); background: var(--surface-overlay); }
.post-card-action.is-danger:hover { color: var(--vision-danger); background: rgba(255,90,95,0.12); }
.post-card-action svg { width: 14px; height: 14px; }

/* O rodapé do popup, separado por uma linha: o que está acima é a peça, o
   que está abaixo é o que se faz com ela. */
/* Os dois rodapés — alterar estado e avaliar — têm a mesma anatomia:
   rótulo em caixa-alta, controle, ação. Um era uma linha solta com um
   `<select>` cru; agora os dois são o mesmo bloco. */
.post-card-foot {
  display: grid; gap: var(--space-3);
  padding-top: var(--space-4);
  border-top: 1px solid var(--border-1);
}
.post-card-foot h3 {
  font-size: 0.68rem; font-weight: 600;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--fg-3);
}
/* Seletor e botão dividem a linha: o campo estica, a ação fica do tamanho
   do texto dela. */
.post-status-row { display: flex; align-items: center; gap: var(--space-3); }
.post-status-row .field { flex: 1; min-width: 0; }
.post-status-row .btn { flex: none; }

@media (max-width: 460px) {
  .post-status-row { flex-direction: column; align-items: stretch; }
  .post-status-row .btn { justify-content: center; }
}

/* Aprovar e reprovar dividem a linha, do mesmo tamanho: a tela não empurra
   para nenhum dos dois. */
.post-review-actions { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); }
.post-review-actions .btn { justify-content: center; }
.post-review-actions svg { width: 15px; height: 15px; }

/* O selo e o "Feito" na mesma linha, alinhados pela base do texto: o botão
   é a resposta àquele selo, e não um controle à parte. `wrap` porque
   "Aguardando Aprovação" mais o botão não cabem na largura do popup no
   celular — quebram em duas linhas em vez de estourar a moldura. */
.post-status-line {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3);
}

/* Menor que os botões de rodapé: é uma ação dentro de um campo de leitura,
   e no tamanho dos outros pareceria a ação principal do painel — que é o
   seletor de estado, logo abaixo. Verde porque encerra o pedido da
   reprovação, e com o texto sobre a própria cor, como `.is-approve`. */
.btn.is-done {
  padding: 5px 12px; font-size: 0.78rem;
  background: var(--vision-success); border-color: var(--vision-success);
  color: #06281a;
}
.btn.is-done svg { width: 14px; height: 14px; }

/* O recado da reprovação, colado ao estado que o explica. */
.post-review-comment {
  margin-top: var(--space-2);
  font-size: 0.9rem; font-style: italic;
  color: var(--fg-2); line-height: 1.55;
}

/* ── O popup que é formulário ────────────────── */
/* Mais largo que o do post: são sete campos, e a copy precisa de linha
   inteira para não virar uma coluna de cinco palavras. */
.post-card.is-form:popover-open { width: min(640px, calc(100vw - 2 * var(--space-4))); }
.post-card.is-form .form-row { margin-bottom: var(--space-4); }
.post-card.is-form .form-actions { margin-top: 0; }

/* ── Artes já guardadas, na edição ───────────── */
/* Miniaturas com caixa de marcar, e não a lista de rótulos do
   `CheckboxSelectMultiple`: "PostImage object (7)" não diz qual peça sai. */
.art-strip { display: flex; flex-wrap: wrap; gap: var(--space-3); }
.art-chip { position: relative; cursor: pointer; }
.art-chip img {
  display: block; width: 72px; aspect-ratio: 1080 / 1350;
  object-fit: cover;
  border: 2px solid var(--border-1); border-radius: var(--radius-sm);
  transition: border-color var(--dur-1), opacity var(--dur-1);
}
/* A caixa some da tela e vira o estado da miniatura: marcada, a arte
   escurece e ganha um × vermelho — que é o que "vai sair" parece. */
.art-chip input { position: absolute; opacity: 0; pointer-events: none; }
.art-chip-mark {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  border-radius: var(--radius-sm);
  background: rgba(255, 90, 95, 0.35);
  color: var(--vision-white);
  opacity: 0; transition: opacity var(--dur-1);
}
.art-chip-mark svg { width: 22px; height: 22px; }
.art-chip input:checked ~ img { border-color: var(--vision-danger); opacity: 0.5; }
.art-chip input:checked ~ .art-chip-mark { opacity: 1; }
.art-chip input:focus-visible ~ img { outline: 2px solid var(--accent); outline-offset: 2px; }

/* O `<input type="file">` do formulário do post: o `.field` das caixas de
   texto não serve a um seletor de arquivo, que o navegador desenha. */
.field-file {
  width: 100%;
  padding: 10px var(--space-3);
  border: 1px dashed var(--border-2); border-radius: var(--radius-sm);
  background: var(--surface-overlay);
  color: var(--fg-2); font-size: 0.88rem; font-family: inherit;
}
.field-file:focus { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ============================================================
   SEÇÕES DA TELA INICIAL
   O seletor de mês e a casca que progresso e calendário dividem: as duas
   recolhem, e o mês que as duas leem é escolhido acima delas. Markup em
   `templates/companies/_month_picker.html` e no `<summary>` de cada seção.
   ============================================================ */

/* ── O seletor de mês ────────────────────────── */
/* Centrado no alto da tela, e não encostado numa borda: ele não pertence a
   nenhuma das duas seções — é o que as duas obedecem, e o meio da tela é o
   único lugar que não sugere dono. */
.month-picker {
  position: relative; z-index: 1;
  display: flex; align-items: center; justify-content: center;
  gap: var(--space-2);
  margin-bottom: var(--space-6);
}

/* O mês, por extenso e no meio das setas: é o rótulo do que está na tela, e
   por isso ele é maior do que os controles que o mudam. */
.month-label {
  min-width: 11ch; text-align: center;
  font-size: 1.02rem; font-weight: 600; color: var(--fg-1);
  font-variant-numeric: tabular-nums;
}

/* As setas: quadradas e discretas até o hover. Elas andam de mês em mês, e
   numa tela em que o conteúdo é o mês inteiro não podem competir com ele. */
.month-step {
  display: grid; place-items: center;
  width: 34px; height: 34px;
  border: 1px solid var(--border-1); border-radius: var(--radius-sm);
  color: var(--fg-2); text-decoration: none;
  transition: border-color var(--dur-1), background var(--dur-1), color var(--dur-1);
}
.month-step:hover {
  border-color: var(--accent); color: var(--fg-1);
  background: var(--surface-overlay);
}
.month-step:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.month-step svg { width: 16px; height: 16px; }
/* Fim da faixa de anos: a seta fica no lugar, apagada. Sumir faria a outra
   pular de posição na virada, e um alvo que se move é um clique errado. */
.month-step.is-off { color: var(--fg-4); opacity: 0.4; cursor: default; }

/* "Hoje" só existe fora do mês corrente, então ele é sempre uma volta: pílula
   em vez de seta, porque não anda um passo — salta. Encostado na seta da
   direita, com uma folga maior, para não ser lido como um terceiro passo. */
.month-now {
  margin-left: var(--space-2);
  padding: 7px 14px; border-radius: var(--radius-pill);
  border: 1px solid var(--border-1);
  font-size: 0.8rem; font-weight: 600;
  color: var(--fg-2); text-decoration: none;
  transition: border-color var(--dur-1), background var(--dur-1), color var(--dur-1);
}
.month-now:hover {
  border-color: var(--accent); color: var(--fg-1);
  background: var(--surface-overlay);
}
.month-now:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ── A casca das seções ──────────────────────── */
/* Cada seção é um `<details>`, como os anos da ficha da empresa: recolher é
   exatamente o que o elemento nativo faz, com teclado e leitor de tela de
   graça, e um acordeão em JavaScript no lugar dele seria a mesma coisa
   escrita de novo e pior.

   Elas nascem recolhidas — a marcação não traz `open` —, e o que fica aberto
   durante a visita é lembrado pelo script do `_sections_script.html`. */
.hub-section {
  position: relative; z-index: 1;
  border-top: 1px solid var(--border-1);
}
.hub-section:last-of-type { border-bottom: 1px solid var(--border-1); }

/* O cabeçalho é a linha inteira: o alvo do clique é a faixa, e não a seta de
   quinze pixels no canto. A seta fica lá porque é ela que **diz** que a
   faixa recolhe — sem ela o cabeçalho seria um título que por acaso responde
   ao clique.

   Grade de duas colunas e não flex: o título e a contagem empilham na
   primeira, e a seta ocupa a segunda inteira, centrada nas duas linhas. */
.hub-section > summary {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 0 var(--space-4);
  padding: var(--space-5) var(--space-3);
  cursor: pointer; list-style: none; user-select: none;
  transition: background var(--dur-1);
}
.hub-section > summary::-webkit-details-marker { display: none; }
.hub-section > summary:hover { background: var(--surface-overlay); }
.hub-section > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

.hub-section > summary h2 {
  grid-column: 1; grid-row: 1;
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 3.4vw, 2rem);
  font-weight: 400; line-height: 1.1; letter-spacing: -0.01em;
}
/* A contagem não se recolhe com o corpo: fechada, a seção ainda tem de
   responder em uma linha o que esconde — é ela que decide se vale abrir. */
.hub-section-count {
  grid-column: 1; grid-row: 2;
  margin-top: 2px;
  font-size: 0.84rem; color: var(--fg-3);
  font-variant-numeric: tabular-nums;
}

/* A seta é a mesma dos anos da ficha, e gira para baixo quando abre: o
   ângulo é o que diz de que lado está o conteúdo. */
.hub-section-caret {
  grid-column: 2; grid-row: 1 / span 2;
  flex: none; width: 18px; height: 18px; color: var(--fg-3);
  transition: transform var(--dur-2) var(--ease-out), color var(--dur-1);
}
.hub-section[open] > summary .hub-section-caret { transform: rotate(90deg); }
.hub-section > summary:hover .hub-section-caret { color: var(--accent); }

.hub-section-body { padding: 0 var(--space-3) var(--space-6); }

/* ============================================================
   PROGRESSO DA TELA INICIAL
   Um anel por empresa, mais o do mês inteiro. Markup em
   `templates/companies/_progress.html` e `_gauge_ring.html`, dados em
   `companies/progresso.py`.
   ============================================================ */

/* O cabeçalho desta seção é o `<summary>` compartilhado, lá em cima. Aqui
   começa o que ele abre. */

/* ── A fileira ───────────────────────────────── */
/* O anel geral à esquerda e os das empresas à direita, numa fileira que
   quebra. `align-items: flex-start` porque os dois blocos têm alturas
   diferentes de propósito — o geral é maior, e alinhar pelo meio o faria
   flutuar acima da fileira. */
.progress-body {
  display: flex; flex-wrap: wrap; align-items: flex-start;
  gap: var(--space-5) var(--space-6);

  /* A trilha é um degrau claro da mesma família do anel, e não um cinza
     neutro: é o que faz o vazio se ler como "falta isto" em vez de como uma
     moldura. Uma cor só para os dois temas — sobre o branco ela é lavanda, e
     sobre o preto um violeta apagado; nos dois casos o arco cheio se destaca
     dela, que é o contraste que decide a leitura do anel. */
  --gauge-track: rgba(169, 147, 255, 0.22);
}

/* ── A faixa das empresas ────────────────────── */
/* Uma fileira única que rola de lado, e não uma grade que quebra em linhas.
   Com quinze ou trinta empresas, a grade cresce para baixo e empurra o
   calendário para fora da tela — a seção que responde "quanto do mês já
   saiu" passaria a ser a tela inteira. Rolando de lado ela tem altura fixa,
   qualquer que seja o tamanho da carteira: o que não cabe está a um arrasto
   à direita, no mesmo gesto do carrossel do post.

   `min-width: 0` porque ela é um item flex: sem isso o conteúdo dita a
   largura mínima, a faixa estoura o `.progress-body` e quem rola de lado
   passa a ser a página. */
.progress-companies {
  flex: 1 1 320px;
  min-width: 0;
  display: flex; flex-wrap: nowrap; gap: var(--space-5);
  list-style: none;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  /* `overflow-x` faz da faixa um recorte também na vertical: sem folga, o
     anel que sobe 2px no hover e o contorno de foco seriam cortados em cima
     e nas pontas. A folga de baixo é a da barra de rolagem, que senão
     cobriria a porcentagem do anel — justamente o que se lê na faixa. */
  scrollbar-width: thin;
  padding: 6px 6px var(--space-2);
}
/* Os anéis não encolhem: a foto do miolo é o que identifica a empresa, e
   espremer quinze para caberem todas devolveria uma fileira de bolinhas
   iguais — que é o problema que a rolagem existe para não ter. */
.progress-companies > li { flex: none; scroll-snap-align: start; }

/* Sem `tabindex` na faixa: cada anel já é um link, e o `Tab` de um para o
   outro rola a faixa sozinho — uma parada a mais só para rolar seria um
   degrau de teclado que não leva a lugar nenhum. */

/* ── O medidor ───────────────────────────────── */
/* Um anel é uma razão contra o seu limite, e não uma pizza: o que está dentro
   dele é *um* número, e é por isso que ele pode ser redondo sem virar um
   gráfico de fatias que ninguém compara direito. */
.gauge {
  display: grid; justify-items: center; gap: var(--space-2);
  text-align: center; text-decoration: none; color: inherit;
}

.gauge-dial {
  position: relative;
  width: var(--gauge-size); height: var(--gauge-size);
}

/* O traço começa às doze horas, e não às três: a volta é lida como um
   relógio, e um anel que começa na lateral parece adiantado. Girar o `<svg>`
   inteiro, e não o círculo, mantém o centro fora da rotação — a foto da
   empresa não pode entrar tombada. */
.gauge-ring {
  display: block; width: 100%; height: 100%;
  transform: rotate(-90deg);
  overflow: visible;
}
.gauge-track {
  fill: none;
  stroke: var(--gauge-track);
  stroke-width: var(--gauge-stroke);
}
.gauge-value {
  fill: none;
  stroke: var(--accent);
  stroke-width: var(--gauge-stroke);
  /* Ponta arredondada, como o resto da plataforma arredonda o que desenha.
     Em 0% o traço não é desenhado — ver o comentário do `_gauge_ring.html`. */
  stroke-linecap: round;
}
/* Cheio vira verde, e só cheio. É a mesma fronteira do semáforo da empresa —
   nada pendente nem reprovado —, aqui restrita ao mês: dar um degrau de cor a
   cada faixa pintaria a tela inteira de amarelo e vermelho ao lado de um
   calendário que já usa as duas cores para outra coisa. A porcentagem
   continua escrita: a cor reforça, não informa sozinha. */
.gauge.is-complete .gauge-value { stroke: var(--vision-success); }

/* O miolo: a porcentagem no anel geral, a foto nos das empresas. */
.gauge-face {
  position: absolute; inset: 0;
  display: grid; place-items: center;
}

.gauge-caption { display: grid; gap: 1px; }
.gauge-name {
  font-weight: 600; color: var(--fg-1);
  line-height: 1.2;
}
.gauge-sub {
  font-size: 0.78rem; color: var(--fg-3);
  font-variant-numeric: tabular-nums;
}

/* ── O anel geral ────────────────────────────── */
.gauge.is-main {
  --gauge-size: clamp(148px, 19vw, 180px);
  --gauge-stroke: 8;
  flex: none;
}
/* O número que a tela lidera, na mesma sans do resto: a fonte de display é
   dos títulos, e um numeral dela aqui viraria enfeite em cima do dado.
   Figuras proporcionais — o `tabular-nums` existe para colunas que se
   alinham, e neste tamanho ele deixa "100%" frouxo. */
.gauge.is-main .gauge-figure {
  font-size: clamp(2.4rem, 5vw, 3rem);
  font-weight: 700; line-height: 1;
  letter-spacing: -0.02em;
  color: var(--fg-1);
}
.gauge.is-main .gauge-name { font-size: 1.02rem; }

/* ── Os anéis das empresas ───────────────────── */
.gauge.is-company {
  --gauge-size: 78px;
  --gauge-stroke: 9;
  width: 104px;
  transition: transform var(--dur-2) var(--ease-out);
}
.gauge.is-company:hover { transform: translateY(-2px); }
.gauge.is-company:hover .gauge-name { color: var(--accent); }
.gauge.is-company:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; border-radius: var(--radius-sm); }
.gauge.is-company .gauge-name {
  font-size: 0.82rem;
  /* Duas linhas de nome e o corte com reticências: numa fileira de quinze, um
     nome comprido que empurrasse o vizinho desalinharia a fileira inteira.
     As duas linhas são reservadas mesmo quando o nome cabe em uma — senão a
     porcentagem do vizinho comprido desceria sozinha, e a fileira perderia a
     linha de base pela qual se compara um anel com o outro. */
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
  min-height: 2.4em;
}
.gauge.is-company .gauge-sub { font-size: 0.72rem; }

/* A foto no miolo, medida pelo anel e não em pixels: assim ela acompanha o
   `--gauge-size` sem uma segunda medida para manter em dia. */
.company-avatar.is-gauge {
  width: 62%; height: 62%;
  font-size: calc(var(--gauge-size) * 0.2);
}

/* ── O critério, por escrito ─────────────────── */
/* O número é uma nota, e nota sem critério não se confere. */
.progress-note {
  margin-top: var(--space-4);
  font-size: 0.78rem; color: var(--fg-3);
  max-width: 62ch; line-height: 1.5;
}
.progress-note strong { color: var(--fg-2); font-weight: 600; }

/* ── Telas estreitas ─────────────────────────── */
@media (max-width: 720px) {
  /* O anel geral encolhe e a fileira passa a caber de ponta a ponta; os das
     empresas cedem menos, porque abaixo de uns sessenta pixels a foto do
     miolo deixa de identificar quem é. */
  .gauge.is-main { --gauge-size: 128px; }
  .gauge.is-company { --gauge-size: 64px; width: 88px; }
  .progress-body { gap: var(--space-4); justify-content: center; }
  /* A faixa passa a ocupar a largura toda, abaixo do anel geral. Alinhada à
     esquerda, e não centrada: numa faixa que rola, centrar o conteúdo que
     transborda empurra o primeiro anel para trás do início da rolagem, e
     ele fica fora de alcance. */
  .progress-companies { flex-basis: 100%; gap: var(--space-4); }
}

/* ============================================================
   CALENDÁRIO DA TELA INICIAL
   Um mês, os posts de todas as empresas. Markup em
   `templates/companies/_calendar.html`, dados em `companies/agenda.py`.
   ============================================================ */

/* O cabeçalho — o mês, a contagem e as setas — saiu daqui: o mês é escolhido
   acima das duas seções, no `.month-picker`, e o título virou o `<summary>`
   que recolhe a seção. Os dois moram no bloco de SEÇÕES DA TELA INICIAL. */

/* ── A grade ─────────────────────────────────── */
/* `table-layout: fixed` porque as sete colunas são os sete dias da semana:
   sem ele, a coluna do dia com quatro empresas ficaria quatro vezes mais
   larga que a do sábado vazio, e a grade deixaria de se ler como um mês.

   `border-collapse` separado com `border-spacing` zero: as células têm borda
   própria, e colapsadas elas dividiriam a linha com a vizinha — o que some
   quando uma das duas ganha a cor do dia de hoje. */
.calendar-table {
  width: 100%;
  table-layout: fixed;
  border-collapse: separate; border-spacing: 0;
}

.calendar-table th {
  padding: 0 0 var(--space-2);
  font-size: 0.68rem; font-weight: 600;
  letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--fg-3); text-align: center;
}
/* O `<abbr>` do navegador vem com pontilhado embaixo e cursor de ajuda: aqui
   ele existe pelo `title`, para o leitor de tela, e não como anotação. */
.calendar-table th abbr { text-decoration: none; cursor: inherit; }

.calendar-day {
  /* Altura mínima num `<td>` não pega; `height` num layout fixo é tratada
     como mínimo, e é ela que dá à semana vazia a mesma presença da cheia. */
  height: 92px;
  vertical-align: top;
  padding: var(--space-2);
  /* Só topo e esquerda: com as bordas separadas, `border` nos quatro lados
     faria duas linhas em cada divisa — a direita de uma célula colada na
     esquerda da vizinha — e a malha sairia com o dobro da espessura por
     dentro e a metade nas beiradas. Assim cada divisa é desenhada uma vez, e
     as duas beiradas que sobram vêm nas duas regras seguintes. */
  border-top: 1px solid var(--border-1);
  border-left: 1px solid var(--border-1);
  background: var(--surface-card);
  transition: background var(--dur-1);
}
.calendar-table .calendar-day:last-child { border-right: 1px solid var(--border-1); }
.calendar-table tbody tr:last-child .calendar-day { border-bottom: 1px solid var(--border-1); }
/* A grade arredonda nos quatro cantos, e só o canto de fora de cada um: uma
   célula do meio arredondada abriria buracos brancos na malha. */
.calendar-table tbody tr:first-child .calendar-day:first-child { border-top-left-radius: var(--radius-md); }
.calendar-table tbody tr:first-child .calendar-day:last-child { border-top-right-radius: var(--radius-md); }
.calendar-table tbody tr:last-child .calendar-day:first-child { border-bottom-left-radius: var(--radius-md); }
.calendar-table tbody tr:last-child .calendar-day:last-child { border-bottom-right-radius: var(--radius-md); }

/* Os dias do mês vizinho continuam na grade — um post do dia 1º num domingo
   tem de aparecer na semana anterior —, mas recuados: a pergunta da tela é
   sobre o mês aberto, e no mesmo viço a primeira semana pareceria ter oito
   dias dele. */
.calendar-day.is-outside { background: var(--bg-1); }
.calendar-day.is-outside .calendar-daynum { color: var(--fg-4); }
.calendar-day.is-outside .calendar-post { opacity: 0.55; }
.calendar-day.is-outside .calendar-post:hover,
.calendar-day.is-outside .calendar-post:focus-visible { opacity: 1; }

.calendar-daynum {
  display: block; margin-bottom: 6px;
  font-size: 0.8rem; font-weight: 600;
  color: var(--fg-3);
  font-variant-numeric: tabular-nums;
}

/* Hoje: o número ganha a cor da marca e um disco, e a célula um anel. O anel
   é `box-shadow` para dentro, e não uma borda mais grossa — uma borda mudaria
   a largura da célula e desalinharia a coluna inteira da semana. */
.calendar-day.is-today {
  background: var(--surface-overlay);
  box-shadow: inset 0 0 0 1px var(--accent);
}
.calendar-day.is-today .calendar-daynum {
  display: inline-grid; place-items: center;
  min-width: 22px; height: 22px; padding: 0 5px;
  border-radius: var(--radius-pill);
  background: var(--accent); color: var(--vision-ink);
}

/* ── Os posts do dia ─────────────────────────── */
/* `flex-wrap` e não uma lista com "+3": os chips são pequenos, e um contador
   de sobra esconderia justamente a peça que alguém veio procurar. A célula
   cresce, e a semana cresce com ela — que é o que um dia cheio de verdade
   parece. */
.calendar-posts { display: flex; flex-wrap: wrap; gap: 5px; }

.calendar-post {
  position: relative;
  display: block; line-height: 0;
  border-radius: var(--radius-pill);
  /* O chip é um link, e o avatar de quem não tem foto são as iniciais em
     texto: sem isto o sublinhado do link risca o "CV" no meio. */
  text-decoration: none;
  transition: transform var(--dur-2) var(--ease-out), opacity var(--dur-1);
}
.calendar-post:hover { transform: translateY(-2px) scale(1.08); z-index: 1; }
.calendar-post:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* O avatar da empresa em tamanho de chip — o degrau que faltava nos três que
   `.company-avatar` já tinha. Quatro deles caberem numa coluna de sete é o
   que decide a medida. */
.company-avatar.is-xs {
  width: 26px; height: 26px;
  font-size: 0.6rem; letter-spacing: 0;
}

/* O estado da peça, no canto do avatar. É `.calendar-post-dot` e não o
   `.status-dot` da empresa de propósito: aquele pulsa, e um mês cheio teria
   quarenta anéis crescendo ao mesmo tempo — o pulso existe para chamar
   atenção para *um* ponto numa lista, e quarenta não chamam para nenhum.

   A borda é da cor do fundo da célula, e não transparente: o ponto fica
   sobre a foto da empresa, e sem o recorte um ponto verde sobre uma arte
   verde desapareceria. */
.calendar-post-dot {
  position: absolute; right: -1px; bottom: -1px;
  width: 10px; height: 10px; border-radius: 50%;
  border: 2px solid var(--surface-card);
  background: currentColor;
}
.calendar-day.is-outside .calendar-post-dot { border-color: var(--bg-1); }
.calendar-day.is-today .calendar-post-dot { border-color: var(--bg-2); }

/* As mesmas quatro cores dos selos do feed, na mesma ordem de leitura:
   pendente é neutro — é a peça que a Vision ainda está montando, e não tem
   recado para dar a ninguém —, aguardando no roxo da marca, aprovado no verde
   e reprovado no vermelho. Cancelado não tem cor porque não chega aqui: a
   peça descartada fica fora do calendário. */
.calendar-post-dot.is-pendente   { color: var(--fg-3); }
.calendar-post-dot.is-aguardando { color: var(--vision-purple); }
.calendar-post-dot.is-aprovado   { color: var(--vision-success); }
.calendar-post-dot.is-reprovado  { color: var(--vision-danger); }

/* ── A legenda ───────────────────────────────── */
/* Abaixo da grade, e não acima: quem lê a tela olha primeiro o mês, e só
   procura o que a cor quer dizer depois de ver uma que não reconhece. */
.calendar-legend {
  display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-5);
  margin-top: var(--space-4);
  list-style: none;
  font-size: 0.78rem; color: var(--fg-3);
}
.calendar-legend li { display: flex; align-items: center; gap: 7px; }
/* Na legenda o ponto está no fluxo, e não colado num avatar: sai do
   absoluto e perde o recorte, que ali não tem o que recortar. */
.calendar-legend .calendar-post-dot {
  position: static; flex: none;
  width: 9px; height: 9px; border: none;
}

/* ── Telas estreitas ─────────────────────────── */
/* Sete colunas continuam sete colunas: um mês em duas colunas não é um mês.
   O que cede é a medida de tudo dentro delas — a célula, o chip e o vão. */
@media (max-width: 720px) {
  /* A margem da página encolhe para o calendário, e não o contrário: cada
     pixel devolvido aqui é dividido por sete colunas, e são eles que decidem
     se dois chips cabem lado a lado numa célula ou se cada post ganha uma
     linha — um dia de seis peças viraria uma fileira de meia tela. */
  .hub-home { padding-inline: var(--space-3); }
  /* O corpo da seção acompanha a margem da página: no celular, os dois
     últimos pixels de cada lado decidem se dois chips cabem numa célula. */
  .hub-section > summary { padding-inline: 0; }
  .hub-section-body { padding-inline: 0; }
  .month-now { margin-left: 0; }
  /* O vão lateral cede antes do chip: a célula tem 44px, e o que decide
     se dois cabem lado a lado são os últimos dois pixels de cada lado. */
  .calendar-day { height: 74px; padding: 4px 2px; }
  .calendar-posts { gap: 2px; justify-content: center; }
  .company-avatar.is-xs { width: 18px; height: 18px; font-size: 0.44rem; }
  .calendar-post-dot { width: 7px; height: 7px; border-width: 1.5px; }
  .calendar-table th { font-size: 0.6rem; letter-spacing: 0.04em; }
  .calendar-daynum { font-size: 0.72rem; margin-bottom: 4px; }
  /* O chip encolheu, e o alvo do dedo não pode encolher junto: o vão entre
     as fileiras dá a altura que falta sem alargar a célula. */
  .calendar-post { padding: 2px 0; }
  .calendar-legend { gap: var(--space-2) var(--space-4); font-size: 0.72rem; }
}

/* ============================================================
   FINANCEIRO
   ============================================================
   A ferramenta mora dentro do hub: não há um token novo aqui, só o
   desenho das peças que existem nesta tela e em nenhuma outra. Os
   componentes da plataforma — .btn, .field, .form-row, .section-label,
   .page-head, .empty-state — vêm de cima. */

.finance-page { max-width: 1320px; }

/* A lista é o que se lê; o formulário é o que se usa. Ele fica à direita e
   acompanha a rolagem: lançar três despesas seguidas não pode obrigar a
   subir de volta a cada uma. */
.finance-split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 380px;
  gap: var(--space-6);
  align-items: start;
}
@media (min-width: 1001px) {
  .finance-form { position: sticky; top: var(--space-5); }
}
@media (max-width: 1000px) {
  /* Numa coluna, o formulário vem primeiro: quem abriu a tela no celular
     veio lançar, e rolar um mês inteiro de extrato para chegar nele seria
     o caminho mais longo até a tarefa mais comum. */
  .finance-split { grid-template-columns: minmax(0, 1fr); }
  .finance-form { order: -1; }
}

/* ── O extrato ───────────────────────────────── */
.ledger-list {
  list-style: none;
  display: grid; gap: var(--space-2);
  margin-bottom: var(--space-6);
}

.ledger-row {
  display: grid;
  /* Larguras fixas nas colunas de fora: o valor precisa alinhar de uma
     linha para a outra, e com colunas elásticas ele dançaria conforme o
     tamanho do nome. */
  grid-template-columns: minmax(0, 1fr) 52px 32px 132px 76px;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  background: var(--surface-card);
  border: 1px solid var(--border-1);
  border-radius: var(--radius-md);
}

/* O lado do lançamento na borda esquerda: entrada e saída na mesma lista,
   sem distinção visual, obrigariam a ler o rótulo de cada linha. */
.ledger-row.is-entrada { border-left: 3px solid var(--vision-success); }
.ledger-row.is-saida { border-left: 3px solid var(--vision-danger); }

.ledger-main { min-width: 0; }
.ledger-name {
  display: block;
  font-size: 0.95rem; font-weight: 600; color: var(--fg-1);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ledger-desc {
  display: block;
  font-size: 0.82rem; color: var(--fg-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.ledger-date {
  font-size: 0.85rem; color: var(--fg-3);
  font-variant-numeric: tabular-nums;
}

.ledger-file {
  display: grid; place-items: center;
  width: 28px; height: 28px;
  color: var(--fg-3); border-radius: var(--radius-sm);
  transition: color var(--dur-1), background var(--dur-1);
}
.ledger-file svg { width: 17px; height: 17px; }
.ledger-file:hover { color: var(--accent); background: var(--surface-overlay); }
.ledger-file:focus-visible { outline: none; box-shadow: var(--shadow-focus); }

.ledger-amount {
  text-align: right;
  font-size: 1rem; font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.ledger-row.is-entrada .ledger-amount { color: var(--vision-success); }
.ledger-row.is-saida .ledger-amount { color: var(--vision-danger); }

/* ── Entrada ou saída: o toggle ──────────────── */
/* O rótulo de um grupo de rádios não é <label> — ele não aponta para um
   campo só —, mas precisa parecer os outros da coluna. */
.form-row > .form-label {
  display: block;
  font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--fg-2); margin-bottom: 7px;
}

/* Uma trilha só, com duas metades e um cursor que desliza entre elas: o
   controle diz que a escolha é uma e exclusiva, o que dois botões separados
   não diziam. Saída à esquerda — ver `forms.arruma_o_tipo`. */
.kind-toggle {
  position: relative;
  display: grid; grid-template-columns: 1fr 1fr;
  padding: 3px;
  background: var(--bg-0);
  border: 1px solid var(--border-1); border-radius: var(--radius-pill);
}

/* O cursor. Nasce à esquerda, sobre a Saída, e a cor sai do lado escolhido —
   as mesmas do extrato, para o formulário e a lista falarem a mesma língua. */
.kind-toggle::before {
  content: "";
  position: absolute; z-index: 0;
  top: 3px; bottom: 3px; left: 3px;
  width: calc(50% - 3px);
  background: var(--vision-danger);
  border-radius: var(--radius-pill);
  transition: transform var(--dur-2) var(--ease-out), background var(--dur-2);
}
/* Nada marcado, nada afirmado: sem isto o cursor descansaria sobre a Saída
   dizendo que ela foi escolhida. Com o padrão do formulário isto não
   acontece — a regra está aqui para o desenho não depender disso. */
.kind-toggle:not(:has(input:checked))::before { opacity: 0; }

.kind-toggle:has(input[value="entrada"]:checked)::before {
  transform: translateX(100%);
  background: var(--vision-success);
}

/* O rádio some e a metade inteira vira o alvo: um alvo de meia largura
   acerta no dedo, um ponto de 14px não. Ele continua no fluxo, recebendo
   foco e as setas do teclado. */
.kind-toggle input {
  position: absolute; opacity: 0; width: 0; height: 0;
  margin: 0; pointer-events: none;
}

.kind-option {
  position: relative; z-index: 1;
  padding: 9px var(--space-3);
  text-align: center; cursor: pointer;
  color: var(--fg-3); font-size: 0.9rem; font-weight: 600;
  border-radius: var(--radius-pill);
  transition: color var(--dur-2);
}
.kind-option:hover { color: var(--fg-1); }

/* O texto escolhido é fixo nos dois temas: o contraste é com o preenchimento
   do cursor, e não com o fundo da página — a mesma regra dos selos de papel. */
.kind-toggle input:checked + .kind-option { color: var(--vision-white); }
.kind-toggle input:checked + .kind-option.is-entrada { color: var(--vision-ink); }

/* O anel de foco vai na trilha: o rádio é invisível, e sem isto quem navega
   por teclado não veria onde está. */
.kind-toggle:has(input:focus-visible) { box-shadow: var(--shadow-focus); }

@media (prefers-reduced-motion: reduce) {
  .kind-toggle::before { transition: none; }
}

/* Sem `:has()` não há cursor deslizante, e a metade escolhida se pinta
   sozinha. Muda a animação, não a leitura. */
@supports not selector(:has(*)) {
  .kind-toggle::before { display: none; }
  .kind-toggle input:checked + .kind-option.is-saida {
    background: var(--vision-danger); color: var(--vision-white);
  }
  .kind-toggle input:checked + .kind-option.is-entrada {
    background: var(--vision-success); color: var(--vision-ink);
  }
}

@media (max-width: 560px) {
  /* O comprovante e a data cedem a coluna antes do valor: a pergunta da
     linha é quanto, e ela não pode quebrar. */
  .ledger-row { grid-template-columns: minmax(0, 1fr) 110px; }
  .ledger-date, .ledger-file, .ledger-row > span:empty { display: none; }
  .ledger-row .btn-mini { grid-column: 2; justify-self: end; }
}

/* ── Financeiro: cabeçalhos de número ────────── */
.finance-heads {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--space-4);
  margin-bottom: var(--space-6);
}
.finance-head {
  display: grid; gap: 4px;
  padding: var(--space-5);
  background: var(--surface-card);
  border: 1px solid var(--border-1);
  border-radius: var(--radius-md);
}
.finance-head-label {
  font-size: 0.68rem; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--fg-3);
}
.finance-figure {
  font-family: var(--font-display);
  font-size: clamp(1.7rem, 4vw, 2.2rem); font-weight: 400;
  color: var(--vision-success);
  font-variant-numeric: tabular-nums;
}
.finance-figure.is-negative { color: var(--vision-danger); }
.finance-head-sub { font-size: 0.82rem; color: var(--fg-3); }

/* ── Faturas ─────────────────────────────────── */
.invoice-list {
  list-style: none; display: grid; gap: var(--space-2);
  margin-bottom: var(--space-6);
}
.invoice-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 150px 170px;
  align-items: center; gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  background: var(--surface-card);
  border: 1px solid var(--border-1);
  border-left: 3px solid var(--vision-warning);
  border-radius: var(--radius-md);
}
/* Paga deixa de pedir atenção: ela continua na lista porque a pergunta do
   mês é "quais faturas vencem", e não "quais faltam". */
.invoice-row.is-paid { border-left-color: var(--vision-success); opacity: 0.72; }
.invoice-main strong { display: block; font-size: 0.95rem; color: var(--fg-1); }
.invoice-sub { font-size: 0.8rem; color: var(--fg-3); }
.invoice-amount {
  text-align: right; font-size: 1rem; font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.invoice-row form { justify-self: end; }

/* ── As abas do mês ──────────────────────────── */
/* Links, e não botões: cada visão é um endereço. */
.ledger-tabs {
  display: flex; gap: var(--space-2);
  margin-bottom: var(--space-4);
}
.ledger-tab {
  padding: 8px var(--space-4);
  background: var(--bg-0); color: var(--fg-2);
  border: 1px solid var(--border-1); border-radius: var(--radius-pill);
  font-size: 0.88rem; font-weight: 600;
  transition: color var(--dur-1), border-color var(--dur-1);
}
.ledger-tab:hover { color: var(--fg-1); border-color: var(--border-2); }
.ledger-tab.is-on {
  color: var(--accent); border-color: var(--accent);
  background: var(--surface-overlay);
}
.ledger-tab:focus-visible { outline: none; box-shadow: var(--shadow-focus); }

/* Atrasada puxa atenção sem virar erro: ela não é um problema, é uma fila. */
.ledger-row.is-late { border-left-color: var(--vision-warning); }

/* ── Referências ─────────────────────────────── */
.finance-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: var(--space-3);
  margin-bottom: var(--space-6);
}
.finance-stats .stat {
  display: grid; gap: 2px;
  padding: var(--space-4);
  background: var(--surface-card);
  border: 1px solid var(--border-1);
  border-radius: var(--radius-md);
}
.finance-stats dt {
  font-size: 0.66rem; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--fg-3);
}
.finance-stats dd {
  font-family: var(--font-display); font-size: 1.5rem;
  font-variant-numeric: tabular-nums; color: var(--fg-1);
}
/* A janela de cada número, por extenso. Três janelas diferentes convivem
   nesta tela, e sem o período escrito cada uma é lida como a do mês. */
.stat-note { font-size: 0.72rem; color: var(--fg-4); }

.finance-note {
  padding: var(--space-4) var(--space-5);
  border: 1px dashed var(--border-1); border-radius: var(--radius-md);
  font-size: 0.85rem; color: var(--fg-3); line-height: 1.6;
}
.finance-note strong { color: var(--fg-2); }

@media (max-width: 660px) {
  .invoice-row { grid-template-columns: minmax(0, 1fr) auto; }
  .invoice-row form, .invoice-row .tag { grid-column: 2; justify-self: end; }
}

/* ── A régua de cartões ──────────────────────── */
/* Rola de lado em vez de quebrar em grade: um cartão é um objeto de
   proporção fixa, e empilhá-los em duas colunas os faria encolher até
   deixarem de parecer cartão. Rolar de lado é o gesto da carteira — e é o
   mesmo recurso da faixa de empresas do progresso. */
.card-rail {
  list-style: none;
  display: flex; flex-wrap: nowrap; gap: var(--space-4);
  overflow-x: auto;
  scroll-snap-type: x proximity;
  /* O vão de baixo é para a sombra do cartão não ser cortada pelo overflow. */
  padding: 2px 2px var(--space-3);
  margin-bottom: var(--space-6);
  scrollbar-width: thin;
}
.card-slot {
  flex: 0 0 auto;
  width: 300px;
  scroll-snap-align: start;
  display: grid; gap: var(--space-3);
}

.credit-card {
  /* 1,586 é a proporção de um cartão de verdade (85,6 × 53,98 mm). É o que
     faz o desenho ser reconhecido antes de ser lido. */
  aspect-ratio: 1.586;
  display: grid; grid-template-rows: auto 1fr auto;
  padding: var(--space-4) var(--space-5);
  border-radius: var(--radius-md);
  color: var(--vision-white);
  background:
    radial-gradient(120% 120% at 100% 0%, rgba(255, 255, 255, 0.14), transparent 55%),
    linear-gradient(135deg, var(--vision-purple-strong), var(--vision-ink));
  box-shadow: var(--shadow-2);
}
/* Cartão desativado sai da paleta da marca: ele continua na régua porque as
   faturas dele continuam, mas não é onde se compra. */
.credit-card.is-inactive {
  background: linear-gradient(135deg, var(--vision-slate), var(--vision-graphite));
  opacity: 0.75;
}

.credit-card-top {
  display: flex; align-items: center; gap: var(--space-3);
}
/* O chip. Puramente decorativo — é o que faz o retângulo virar cartão num
   relance, antes de qualquer texto ser lido. */
.credit-card-chip {
  flex: none; width: 30px; height: 22px;
  border-radius: 5px;
  background: linear-gradient(135deg, #e8c86a, #b8912f);
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.18);
}
.credit-card-name {
  font-weight: 600; font-size: 0.95rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.credit-card-body { align-self: center; display: grid; gap: 2px; }
.credit-card-label {
  font-size: 0.66rem; letter-spacing: 0.08em; text-transform: uppercase;
  color: rgba(255, 255, 255, 0.72);
}
.credit-card-amount {
  font-family: var(--font-display);
  font-size: 1.75rem; font-weight: 400;
  font-variant-numeric: tabular-nums;
}

.credit-card-foot {
  display: flex; justify-content: space-between;
  font-size: 0.74rem; color: rgba(255, 255, 255, 0.78);
  font-variant-numeric: tabular-nums;
}
.credit-card-foot b { font-weight: 600; color: rgba(255, 255, 255, 0.55); }

/* Os limites ficam **fora** do cartão: o cartão mostra a fatura do mês
   escolhido, e o limite é de agora — dentro do mesmo retângulo, os dois
   seriam lidos como a mesma janela de tempo. */
.card-limits {
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3);
  padding: 0 2px;
}
.card-limits strong {
  display: block; font-size: 0.95rem;
  font-variant-numeric: tabular-nums; color: var(--fg-1);
}
.card-limits strong.is-negative { color: var(--vision-danger); }
.card-limit-label {
  display: block;
  font-size: 0.64rem; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--fg-3);
}

.card-actions {
  display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center;
}

@media (max-width: 560px) {
  /* Um pouco mais estreito que a tela, de propósito: a borda do cartão
     seguinte aparecendo é o que anuncia que a régua rola. */
  .card-slot { width: min(82vw, 300px); }
  /* A régua sangra até a borda da tela; o vão lateral vira scroll. */
  .card-rail { margin-inline: calc(var(--space-3) * -1); padding-inline: var(--space-3); }
}

/* ── Paginação ───────────────────────────────── */
.paginacao {
  display: flex; align-items: center; justify-content: center;
  gap: var(--space-4);
  margin-bottom: var(--space-6);
}
.paginacao-passo {
  display: grid; place-items: center;
  width: 34px; height: 34px;
  color: var(--fg-2);
  border: 1px solid var(--border-1); border-radius: var(--radius-pill);
  transition: color var(--dur-1), border-color var(--dur-1);
}
.paginacao-passo svg { width: 17px; height: 17px; }
.paginacao-passo:hover { color: var(--accent); border-color: var(--accent); }
.paginacao-passo:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
/* Apagada, não sumida: sumindo, a outra seta pularia de lugar na primeira e
   na última página. */
.paginacao-passo.is-off { color: var(--fg-4); border-color: var(--border-1); opacity: 0.45; }
.paginacao-conta {
  font-size: 0.85rem; color: var(--fg-3);
  font-variant-numeric: tabular-nums;
}

/* Duas ações na última coluna da linha. Sem isto elas viram duas colunas do
   grid e desalinham o valor de todas as outras linhas da lista. */
.row-actions { display: flex; gap: var(--space-2); justify-content: flex-end; }


/* ============================================================
   DEMANDAS EXTRAS — o trabalho do mês que não é post
   ============================================================ */

/* Duas colunas, e não as três do feed. O card do post é uma arte, e três
   colunas são a grade que ele existe para prever; este card é texto, e em
   três colunas o nome sairia cortado no meio em qualquer tela de notebook.
   No celular vira uma só: 160px de largura não cabem "Banner da home do
   site" sem quebrar em quatro linhas. */
.demand-grid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-3);
}
@media (max-width: 560px) { .demand-grid { grid-template-columns: 1fr; } }

/* O cabeçalho da seção herda o espaçamento do de cancelados — as duas
   descem a mesma distância do que vem acima delas. */
.section-head.is-demandas { margin-top: var(--space-7); }

/* Sem proporção fixa, ao contrário do `.post-tile`: não há imagem para
   reservar espaço, e uma altura mínima é o que mantém a fileira regular
   quando um nome ocupa uma linha e o vizinho ocupa duas. */
.demand-tile {
  position: relative;
  /* Coluna flex, e não grid: é o que deixa o rodapé de sinais descer para
     a base com um `margin-top: auto`, sem precisar declarar linhas para um
     card cujo conteúdo é variável — há demanda com dois sinais, com um e
     com nenhum. */
  display: flex; flex-direction: column; gap: 6px;
  width: 100%; min-height: 132px;
  padding: var(--space-4);
  text-align: left;
  border: 1px solid var(--border-1); border-radius: var(--radius-md);
  background: var(--surface-card); cursor: pointer;
  transition: border-color var(--dur-1), transform var(--dur-2) var(--ease-out),
              box-shadow var(--dur-2);
}
.demand-tile:hover {
  border-color: var(--accent);
  transform: translateY(-3px);
  box-shadow: var(--shadow-3);
}
.demand-tile:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* A data vem acima do nome e menor que ele: ela ordena a lista, mas o que
   identifica a demanda é o nome — no card do post é o contrário, porque lá
   a peça é a imagem e a data é a única palavra. */
.demand-tile-date {
  font-size: 0.72rem; font-weight: 600;
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--fg-3);
}
.demand-tile-name {
  font-size: 1rem; font-weight: 600; line-height: 1.35;
  color: var(--fg-1);
  /* Até três linhas, e depois reticências: um nome comprido não pode
     esticar o card e desalinhar a fileira inteira. */
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Os sinais de conteúdo, colados no rodapé do card: é o que esta lista tem
   no lugar da prévia. `margin-top: auto` os empurra para a base, então eles
   ficam alinhados entre os cards da fileira mesmo quando um nome ocupa uma
   linha e o vizinho ocupa três. */
.demand-tile-marks {
  display: flex; flex-wrap: wrap; gap: 6px;
  margin-top: auto; padding-top: var(--space-3);
}
.demand-mark {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 9px; border-radius: var(--radius-pill);
  border: 1px solid var(--border-1);
  background: var(--surface-overlay);
  font-size: 0.68rem; font-weight: 600;
  color: var(--fg-3);
}
.demand-mark svg { width: 12px; height: 12px; }

/* O ícone de ampliar do card de post serve aqui, e num card sem imagem ele
   precisa de contraste com o fundo claro — o do post fica sobre a arte. */
.demand-tile .post-tile-open { color: var(--fg-3); }

/* O painel é o `.post-card` inteiro; daqui sai só o que difere. Sem
   carrossel, o vão entre o cabeçalho e os campos fica grande demais para
   um painel que costuma ter três seções curtas. */
.demand-card:popover-open { gap: var(--space-3); }

/* A caixa de marcar do formulário, com o nome do arquivo ao lado. O
   `align-items: center` alinha a caixa com a primeira linha do texto, e não
   com o bloco inteiro, quando o nome do arquivo quebra em duas. */
.check-row {
  display: flex; align-items: center; gap: var(--space-3);
  font-size: 0.9rem; color: var(--fg-2); cursor: pointer;
}
.check-row input { flex: none; width: 16px; height: 16px; accent-color: var(--accent); }
.check-row strong { color: var(--fg-1); font-weight: 600; word-break: break-word; }
