/*
 * Isolamento mínimo entre o preview aprovado e os estilos globais canônicos.
 * Não redefine o design: apenas impede a tipografia/entrelinha canônicas e o
 * rodapé global de alterarem as métricas efetivamente renderizadas no preview.
 */
.site-shell {
  /* No preview executável não há @font-face de Inter: o stack aprovado resolve em system-ui.
     O Next canônico carrega Inter localmente; removê-la só neste shell preserva a métrica real. */
  --font-sans: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.5;
  letter-spacing: normal;
}

.site-shell :is(h3, h4, legend) {
  font-family: var(--font-sans);
}

/* BeeDesign A1: h1/h2 da home pública passam de system-ui (Segoe UI) para Oxanium — unifica a
   identidade de display com o resto do produto. Gate visual deve MEDIR o hero (métrica muda). */
.site-shell :is(h1, h2) {
  font-family: var(--font-oxanium), ui-sans-serif, system-ui, sans-serif;
}

body:has(.site-shell) footer[aria-label="Informações legais"] {
  display: none;
}

html:has(.site-shell)::-webkit-scrollbar,
html:has(.site-shell) *::-webkit-scrollbar {
  width: 15px;
  height: 15px;
}

html:has(.site-shell)::-webkit-scrollbar-track,
html:has(.site-shell) *::-webkit-scrollbar-track,
html:has(.site-shell)::-webkit-scrollbar-thumb,
html:has(.site-shell) *::-webkit-scrollbar-thumb {
  background: revert;
  border-radius: revert;
}

/* O preview só demonstrava sucesso. Estes dois estados vêm do contrato canônico de login. */
.auth-page .login-status-error {
  border-color: #e4b5b5;
  background: #fff1f1;
  color: #9d2424;
}

.auth-page .login-status-notice {
  border-color: #b8d8c5;
  background: var(--green-soft);
  color: var(--green);
}

html[data-theme="dark"] .auth-page .login-status-error {
  border-color: #773f45;
  background: #2d1c22;
  color: #ffb8be;
}

.auth-page .remember-field:has(input:disabled) {
  cursor: default;
}

/* ── /inicio (UI V2 · Bloco B) ───────────────────────────────────────────────────────────────── */

/* O hero do preview reserva ~34% da faixa para o slot da EMPRESA ATIVA. Essa identidade é canônica
   e já vive na topbar do cromo (ClienteContexto) — repeti-la no hero seria dado encenado. Sem o
   slot, o hero volta a coluna única em vez de deixar a faixa direita vazia. */
.workspace-intro-compact:not(:has(.workspace-intro-context)) {
  grid-template-columns: minmax(0, 1fr);
}

/* O preview só demonstrava métricas COM dado. "Sem dado" é estado canônico do /inicio (ausência
   nunca vira 0 nem 0%) e precisa deixar de parecer um valor apurado — mesma mecânica de modificador
   que o próprio preview usa em `.has-attention`. */
.portfolio-metrics .is-sem-dado dd {
  color: var(--muted);
  font-size: 1.05rem;
  font-style: italic;
  font-weight: 560;
}

/* A legenda de um KPI monetário carrega o SELO DE PROVENIÊNCIA canônico (D-223: nunca um valor nu),
   que o preview não modelava. Alinha o selo à linha do texto sem alterar a métrica do bloco. */
.portfolio-metrics > div > span {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-wrap: wrap;
}

/* O preview tem UMA decisão com UM botão no rodapé do cartão; o /inicio tem ATÉ 3 ações, cada uma
   com o seu destino real. O CTA passa a viver dentro do item da lista — só o respiro acima dele
   não existia no bloco original. */
.next-action li .button {
  margin-top: 8px;
  justify-self: start;
}

/* ── Carteira (UI V2 · Bloco C) ──────────────────────────────────────────────────────────────── */

/* O hub Carteira envolve TODAS as sub-rotas num wrapper da pele v2 (`app/(workspace)/carteira/
   layout.tsx`), que fica entre o `.workspace-content` do cromo aprovado — quem dá o espaçamento entre
   os blocos — e o conteúdo da rota. Com a flag mestra ligada o wrapper repete essa pilha; sem isto as
   seções V2 da Carteira colariam umas nas outras. */
.carteira-v2-stack {
  display: grid;
  gap: 18px;
  align-content: start;
}
@media (max-width: 480px) {
  .carteira-v2-stack {
    gap: 14px;
  }
}

/* Componente CANÔNICO alojado dentro de um card do preview (tabelas de destino, agenda do calendário,
   etapas da importação…): a moldura é a do card do preview, não a do card canônico — duas bordas
   empilhadas foi exatamente o defeito que reprovou a calculadora. Só a MOLDURA é neutralizada;
   tipografia, tokens e comportamento do componente canônico ficam intactos. */
.v2-slot-canonico > .card {
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}

/* As duas visões da carteira (Lista | Monitor) ficam MONTADAS ao mesmo tempo — trocar por `hidden`
   evita reler a primeira página como se fosse dado fresco. O invólucro que isso exige não pode engolir
   o espaçamento que o `.workspace-content` dá aos blocos: reproduz a mesma pilha. */
.portfolio-view {
  display: grid;
  gap: 18px;
  align-content: start;
}
.portfolio-view[hidden] {
  display: none;
}
@media (max-width: 480px) {
  .portfolio-view {
    gap: 14px;
  }
}

/* Os DOIS destinos canônicos de cada prazo (`DeadlineStrip.ItemPrazo`): "Ver clientes" condicional e
   "Ver calendário" sempre (F2). O preview desenha UM link como 3ª célula (`.deadline-item > a`);
   com dois, eles precisam de um invólucro — que herda a métrica e o comportamento responsivo que a
   folha aprovada dava ao link solto, sem inventar nada. */
.deadline-item > .deadline-item-destinos {
  min-width: 0;
  display: grid;
  justify-items: end;
  gap: 4px;
}
.deadline-item > .deadline-item-destinos a {
  color: var(--green);
  font-size: var(--fs-caption);
  font-weight: 700;
  white-space: nowrap;
}
/* A seta decorativa dentro do link não é o `span` de título do prazo (`.deadline-item > div span`). */
.deadline-item > .deadline-item-destinos a span {
  color: inherit;
  font-size: inherit;
  font-weight: inherit;
}
@media (max-width: 680px) {
  .deadline-item > .deadline-item-destinos {
    grid-column: 2;
    justify-items: start;
  }
}

/* "Próximos vencimentos" com fonte maior (decisão do Felipe 11/10). Só tipografia, na escala
   BeeDesign (text-base 16 · text-sm 14 · text-xs 12 · text-3xl 30), escopada ao painel
   `.deadlines-panel` para vencer a especificidade do piso G9 (`.deadline-item > div small`) sem
   tocar nas demais superfícies. Nenhum texto, cor ou lógica novos. */
.deadlines-panel .deadlines-heading .workspace-kicker {
  font-size: 16px;
  font-weight: 600;
}
.deadlines-panel .deadlines-heading h2 {
  font-size: 14px;
}
.deadlines-panel .deadline-item {
  grid-template-columns: minmax(56px, auto) minmax(0, 1fr) auto;
}
.deadlines-panel .deadline-item > strong {
  font-size: 30px;
}
.deadlines-panel .deadline-item > strong small {
  font-size: var(--fs-caption);
}
.deadlines-panel .deadline-item > div span {
  font-size: 16px;
  font-weight: 500;
}
.deadlines-panel .deadline-item > div small {
  font-size: var(--fs-caption);
}
.deadlines-panel .deadline-item > a,
.deadlines-panel .deadline-item > .deadline-item-destinos a {
  font-size: 14px;
}
@media (max-width: 680px) {
  .deadlines-panel .deadline-item {
    grid-template-columns: minmax(56px, auto) minmax(0, 1fr);
  }
}

/* O cockpit canônico tem 5 KPIs (o preview modelava 4) — sem isto o 5º cai sozinho numa 2ª linha
   ocupando 1/4 da faixa. Só acima do ponto em que o próprio preview já quebra para 2 colunas. */
@media (min-width: 981px) {
  .manager-kpis:has(> article:nth-child(5)) {
    grid-template-columns: repeat(5, minmax(0, 1fr));
  }
}

/* "sem dado" é estado canônico (ausência nunca vira 0/0%) e não pode parecer um valor apurado —
   mesma mecânica de modificador que o preview usa em `.is-attention`. */
.manager-kpis article.is-sem-dado strong,
.wave-stat-grid article.is-sem-dado strong {
  color: var(--muted);
  font-style: italic;
}

/* A fila agrupa por PROBLEMA e guarda a lista por cliente atrás de um `<details>` (mesma afordância do
   bloco legado) — o preview lista N itens fixos e não tinha esse expansor. */
.action-queue .fila-v2-detalhe {
  padding: 4px 0 8px;
  border-bottom: 1px solid var(--line);
}
.action-queue .fila-v2-detalhe summary {
  color: var(--muted);
  font-size: var(--fs-caption);
  cursor: pointer;
}
.action-queue .fila-v2-detalhe ul {
  display: grid;
  gap: 4px;
  margin-top: 6px;
  list-style: none;
}
.action-queue .fila-v2-detalhe li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 6px;
  font-size: var(--fs-caption);
}
.action-queue .fila-v2-detalhe button {
  border: 0;
  background: none;
  color: var(--navy-950);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
html[data-theme="dark"] .action-queue .fila-v2-detalhe button {
  color: var(--white);
}
.action-queue .fila-v2-detalhe span {
  color: var(--muted);
}
.action-queue .fila-v2-vazio {
  padding: 12px 0;
  color: var(--muted);
  font-size: var(--fs-caption);
}

/* O dossiê canônico publica 5 contadores (o preview desenhava 6 fatos estáticos) e cada um é um
   ATALHO para a faceta que detalha o número — o preview não tinha ação nenhuma nesse bloco. */
@media (min-width: 1181px) {
  .dossier-facts:not(:has(> :nth-child(6))) {
    grid-template-columns: repeat(5, minmax(0, 1fr));
  }
}
.dossier-facts > div > button {
  display: grid;
  gap: 3px;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

/* O tablist canônico do dossiê é de BOTÕES (foco roving, setas, `aria-controls`), não de âncoras como
   no preview, e mantém os grupos da D-239 como divisores. Mesma aparência das abas aprovadas. */
.dossier-tabs {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 10px;
}
.dossier-tabs-grupo > p {
  margin-bottom: 4px;
  color: var(--muted);
  font-size: var(--fs-caption);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.dossier-tabs-grupo > div {
  display: flex;
  flex-wrap: wrap;
  gap: 3px;
}
.dossier-tabs button {
  min-height: 30px;
  padding: 0 11px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: var(--white);
  color: var(--muted);
  font: inherit;
  /* F6 — controle interativo: 11px é o piso de legibilidade adotado nesta rodada. */
  font-size: var(--fs-button);
  font-weight: 600;
  cursor: pointer;
}
.dossier-tabs button.is-active {
  border-color: var(--yellow);
  background: var(--yellow-soft);
  color: var(--navy-950);
}
html[data-theme="dark"] .dossier-tabs button.is-active {
  color: var(--white);
}
.dossier-cadastro-incompleto {
  color: #986400;
  font-weight: 600;
}
/* F7: `#986400` é âmbar de PAPEL — sobre o `--paper` escuro do dark ele quase some. O token de
   âmbar profundo do próprio preview já é resolvido por tema (`--yellow-deep`), e é ele que garante
   o contraste do aviso nos dois. */
html[data-theme="dark"] .dossier-cadastro-incompleto {
  color: var(--yellow-deep);
}

/* F14: o painel da faceta é um `role="tabpanel"` com `tabIndex=0` (o tablist canônico move o foco
   para ele). A folha aprovada só desenha anel de foco para `a/button/input/summary` — um painel
   focável sem anel deixa o usuário de teclado sem saber onde está. Mesmo anel, mesmos valores. */
.dossier-facet:focus-visible {
  outline: 3px solid rgba(244, 188, 25, 0.55);
  outline-offset: 4px;
}

/* `/carteira/documentos`: a granularidade real é EMPRESA → N competências (decisão da fatia). Cada
   empresa é um bloco dentro do painel de competências, com a tabela do preview por dentro. */
.competence-panel .documentos-v2-empresa {
  padding: 12px 14px;
  border-top: 1px solid var(--line);
}
.competence-panel .documentos-v2-empresa:first-of-type {
  border-top: 0;
}
.documentos-v2-empresa h3 {
  color: var(--navy-950);
  font-size: var(--fs-caption);
  font-weight: 700;
}
html[data-theme="dark"] .documentos-v2-empresa h3 {
  color: var(--white);
}
.documentos-v2-empresa .dossier-card-heading p,
.documentos-v2-sem-competencia,
.documentos-v2-foco {
  color: var(--muted);
  font-size: var(--fs-caption);
}

/* Sem filtro de mês não existe grade mensal para desenhar — o layout volta a uma coluna em vez de
   deixar a faixa direita vazia (mesma mecânica do hero do /inicio). */
.calendar-layout:not(:has(> aside)) {
  grid-template-columns: minmax(0, 1fr);
}

/* Resumo canônico de próximos prazos: chips clicáveis que ABREM o detalhe do evento (o preview não
   modela este bloco — ele traz um grid de números sem lastro no lugar). */
.calendario-v2-proximos {
  padding: 12px 14px;
}
.calendario-v2-proximos ul {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  list-style: none;
}
.calendario-v2-proximos button {
  padding: 5px 10px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--white);
  color: var(--muted);
  font: inherit;
  /* F6 — chip clicável: piso de 11px como nos demais controles. */
  font-size: var(--fs-button);
  cursor: pointer;
}
.calendario-v2-proximos button strong {
  color: var(--navy-950);
}
html[data-theme="dark"] .calendario-v2-proximos button strong {
  color: var(--white);
}
.calendario-v2-proximos > p {
  color: var(--muted);
  font-size: var(--fs-caption);
}

/* Notas canônicas que o preview não modelava (ele só demonstrava sucesso, sem "sem dado"). */
.destinos-v2-nota,
.evolucao-v2-sem-dado {
  color: var(--muted);
  font-size: var(--fs-caption);
}

/* ── Simulador (UI V2 · Bloco D) ─────────────────────────────────────────────────────────────── */

/* A coluna do dashboard já é uma grade (`.calculator-dashboard`), mas o resultado canônico entra como
   UM filho dela; a pilha interna precisa do mesmo respiro entre blocos. */
.calculator-dashboard-v2 {
  min-width: 0;
  display: grid;
  gap: 18px;
  align-content: start;
}

/* O `decision-summary-card` do preview é uma grade de DUAS colunas (síntese | métricas). A coluna de
   métricas não entra: os números canônicos vivem na `LinhaKpiResultado`, que é o bloco ② da ordem
   D-252 — trazê-los para cá os anteciparia à comparação. Sem a 2ª coluna o cartão volta a uma só, em
   vez de deixar metade da faixa vazia (mesma mecânica do hero do /inicio). */
.decision-summary-card:not(:has(.decision-summary-metrics)) {
  grid-template-columns: minmax(0, 1fr);
}
.decision-summary-card:not(:has(.decision-summary-metrics)) .decision-summary-main {
  border-right: 0;
}

/* O selo do veredito canônico é SEMPRE "estimativa" (ADR-009: a comparação da lei vigente não conclui
   sozinha). O `regime-verdict-badge` do preview é verde — leria como veredito fechado. Vira âmbar, o
   mesmo tom que o banner canônico usa para "a confirmar". */
.decision-summary-card .regime-verdict-badge {
  border-color: rgba(244, 188, 25, 0.3);
  background: rgba(244, 188, 25, 0.1);
  color: #ffd769;
}
.decision-summary-card .regime-verdict-badge i {
  background: #f4bc19;
  box-shadow: 0 0 0 3px rgba(244, 188, 25, 0.12);
}

/* Acento lateral com FUNÇÃO semântica: o banner canônico pinta a borda esquerda de âmbar quando falta
   dado para concluir e de verde quando conclui. A barra fixa verde→amarela do preview não carrega
   estado — aqui ela passa a carregar, senão a cor afirmaria "concluído" onde o texto nega. */
.decision-summary-card.is-pendente .decision-summary-main::before {
  background: linear-gradient(180deg, var(--yellow), #f4bc19);
}

/* "Próximo passo" — a ação que fecha a comparação. Não existe no preview (ele só demonstrava o caso
   concluído); herda a tipografia do cartão escuro e ganha destaque de nota. */
.decision-summary-main .decision-summary-proximo-passo {
  margin-top: 4px;
  padding: 8px 10px;
  border-left: 2px solid var(--yellow);
  border-radius: 0 6px 6px 0;
  background: rgba(255, 255, 255, 0.05);
  color: #d6e2e8;
  font-size: var(--fs-caption);
  line-height: 1.5;
}
.decision-summary-main .decision-summary-proximo-passo strong {
  color: var(--white);
}

/* Memória de cálculo + fontes/base legal são DOIS acordeões canônicos alojados no MESMO cartão de
   rastreabilidade do preview. `v2-slot-canonico > .card` (regra da Carteira) não os alcança: o `.card`
   deles fica um nível abaixo da própria `<section>` raiz. Escopado a este cartão — só a MOLDURA some,
   o acordeão, o conteúdo e as fontes ficam intactos. */
.calculation-memory.v2-slot-canonico > section > .card {
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}
.calculation-memory.v2-slot-canonico > section + section > .card {
  border-top: 1px solid var(--line);
}

/* Wizards (`/simulador/operacao`, `/servico`, `/nfe`): o conteúdo da rota é uma pilha de blocos
   irmãos (cabeçalho, alternância, avisos, grade) dentro do `.workspace-content` do cromo. */
.simulacao-v2-stack {
  display: grid;
  gap: 18px;
  align-content: start;
}
@media (max-width: 480px) {
  .simulacao-v2-stack {
    gap: 14px;
  }
}

/* A costura entre os wizards é a `AlternanciaVendaServico` CANÔNICA (3 rotas reais), não a
   `simulation-tabs` demonstrativa do preview — só o respiro do bloco vem daqui. */
.simulacao-v2-alternancia,
.simulacao-v2-passos {
  min-width: 0;
}

/* Sem simulação não existe coluna de resultado (ausência permanece ausência). A grade volta a uma
   coluna em vez de reservar 1.32fr de vazio — mesma mecânica do calendário e do hero do /inicio. */
.simulation-workspace-grid:not(:has(.simulation-results-column > *)),
.invoice-simulator-layout:not(:has(.simulation-results-column > *)) {
  grid-template-columns: minmax(0, 1fr);
}
.simulation-workspace-grid:not(:has(.simulation-results-column > *)) .simulation-results-column,
.invoice-simulator-layout:not(:has(.simulation-results-column > *)) .simulation-results-column {
  display: none;
}

/* ── Classificação (UI V2 · Bloco E) ─────────────────────────────────────────────────────────── */

/* A aside "Leitura segura / Como interpretar" do preview é copy NOVA (3 passos + nota de projeção),
   sem contraparte canônica em nenhuma superfície da Central — e a regra da rodada só autoriza portá-la
   com copy canônica equivalente. Sem a aside, a grade volta a UMA coluna em vez de deixar 265px vazios
   (mesma mecânica do hero do /inicio, do calendário e da coluna de resultado do simulador). */
.query-layout:not(:has(> aside)) {
  grid-template-columns: minmax(0, 1fr);
}

/* "Por descrição" do modo PRODUTOS não tem campo Ano (a busca textual de produto não recebe ano — só
   a de serviço recebe). A grade `is-description` do preview reserva 100px para esse select mesmo
   quando ele não existe, empurrando o botão para uma coluna de 100px e deixando a faixa final vazia. */
.query-form-grid.is-description:not(:has(select)) {
  grid-template-columns: minmax(0, 1fr) auto;
}

/* A `batch-side-card` do preview NÃO é portada (F13): das cinco frases que a rodada tinha escrito
   nela, só uma tem literal canônico ("Decisões em grupo"), e aside de um marcador é moldura. Sem a
   aside, a grade volta a UMA coluna em vez de reservar 265px vazios — mesma mecânica da
   `query-layout`, do hero do /inicio e da coluna de resultado do simulador. */
.batch-layout:not(:has(> aside)) {
  grid-template-columns: minmax(0, 1fr);
}

/* Blocos canônicos dentro de um `batch-step` (a amostra das primeiras linhas do arquivo e a linha de
   ações do mapeamento). O passo 03 do preview não classifica nada — não tem amostra nem botões —,
   então não há métrica aprovada para reaproveitar; estas duas regras só dão o respiro do passo. */
.batch-step .batch-step-bloco {
  margin-top: 10px;
}
.batch-step .batch-step-acoes {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  margin-top: 10px;
}

/* ── Demais rotas: /agenda · /projecao · /relatorios · /impacto-release (UI V2 · Bloco F) ────── */

/* `/projecao` e `/relatorios` mantêm o wrapper `data-skin="v2"` que a rota sempre teve — ele fica
   ENTRE o `.workspace-content` do cromo (quem dá o espaçamento entre blocos) e o conteúdo. Com a
   flag mestra ligada o wrapper repete essa pilha, senão as seções V2 colariam umas nas outras
   (mesma mecânica de `.carteira-v2-stack` e `.simulacao-v2-stack`). */
.workspace-rota-v2-stack {
  display: grid;
  gap: 18px;
  align-content: start;
}
@media (max-width: 480px) {
  .workspace-rota-v2-stack {
    gap: 14px;
  }
}

/* AGENDA ------------------------------------------------------------------------------------- */

/* O `agenda-list-card` do preview sempre tem um `wave-card-heading` acima da lista; sem ele (o h2
   "O que exige decisão" e o selo "Dados demonstrativos" são copy do preview) o `border-top` da
   primeira tarefa duplicaria a borda superior do próprio card. */
.agenda-list-card > .agenda-task-list > li:first-child > article,
.agenda-list-card > .agenda-v2-grupo:first-child .agenda-task-list > li:first-child > article {
  border-top: 0;
}

/* Estado "nenhuma tarefa nesta visão" e o cabeçalho de cada grupo da visão "Por empresa": conteúdo
   canônico sem modelo no preview — herdam o respiro horizontal das linhas de tarefa (14px). */
.agenda-list-card > .agenda-v2-vazio {
  margin: 0;
  padding: 13px 14px;
  color: var(--muted);
  font-size: var(--fs-caption);
}
.agenda-list-card > .agenda-v2-grupo {
  padding: 13px 14px 0;
}
.agenda-list-card > .agenda-v2-grupo > .workspace-kicker {
  margin-bottom: 6px;
}
/* O grupo já dá o respiro lateral; a lista dentro dele volta a alinhar com a borda do card. */
.agenda-v2-grupo .agenda-task-list > li > article {
  margin: 0 -14px;
}

/* Resolução registrada numa tarefa concluída — texto do usuário, sem modelo no preview. Nota citada,
   nunca confundida com a descrição da tarefa. */
.agenda-task-main > .agenda-v2-resolucao {
  margin: 4px 0 0;
  padding: 5px 7px;
  border-left: 2px solid var(--line-strong);
  background: var(--paper-deep);
  color: var(--muted);
  font-size: var(--fs-caption);
  line-height: 1.45;
}

/* PROJEÇÃO ----------------------------------------------------------------------------------- */

/* O `projection-source-card` do preview traz 3 fatos fixos ("Regime atual declarado", "Atividade",
   "Confiança"); o canônico publica UM (o critério visível "Projeção de: X") — e com uma origem só
   nem seletor existe. `auto-fit` faz a faixa acompanhar o que REALMENTE existe em vez de reservar
   duas colunas vazias (mesma mecânica do hero do /inicio e da coluna de resultado do simulador). */
.projection-source-card {
  grid-template-columns: minmax(260px, 1.3fr) repeat(auto-fit, minmax(120px, 0.6fr));
}
.projection-source-card .projecao-v2-ajuda {
  margin: 0;
  color: var(--muted);
  font-size: var(--fs-caption);
  line-height: 1.4;
}

/* Cada linha do gráfico é ano + faixas. O `<small>` da 3ª coluna do preview carregava a "fase" de um
   cenário demonstrativo; o canônico não publica fase POR ANO no gráfico (ela vive inteira na régua e
   na tabela do cronograma), então a linha volta a duas colunas em vez de reservar 135px vazios. */
.projection-rows > div:not(:has(> small)) {
  grid-template-columns: 34px minmax(0, 1fr);
}

/* As DUAS séries canônicas do gráfico (a comparação de 3 REGIMES do preview não é portada): a carga
   de hoje é CONTEXTO (recessiva) e o total projetado é o ponto — e projeção, no cromo aprovado, é
   amarelo. Só definem o `--regime-color` que o preview já usa nas faixas e na legenda.
   P163-3 (gate ao vivo do Felipe 05/08: "paleta ficou ruim" — validador confirmou: `--muted`
   #5f6f7e × `--yellow-deep` #875b00 tem ΔE 13,9, abaixo do piso 15 até para visão normal): o
   projetado troca o ocre por um âmbar com luz (#b58900 — ΔE 20,3 no claro / 16,8 no escuro,
   contraste ≥3:1 nos dois temas). O atual segue neutro DE PROPÓSITO (de-ênfase; rótulo direto ao
   lado é o canal secundário) — no escuro sobe um degrau (#7e93a5) para não afundar no navy. */
.projecao-v2-serie-atual {
  --regime-color: var(--muted);
}
.projecao-v2-serie-projetado {
  --regime-color: #b58900;
}
html[data-theme="dark"] .projecao-v2-serie-atual {
  --regime-color: #7e93a5;
}
html[data-theme="dark"] .projecao-v2-serie-projetado {
  --regime-color: #b58900;
}

/* Título/apoio e nota final do gráfico — copy canônica, sem parágrafo modelado no preview. */
.projection-chart-card > .projecao-v2-nota {
  margin: 0 0 7px;
  color: var(--muted);
  font-size: var(--fs-caption);
  line-height: 1.45;
}
.projection-chart-card > .projection-rows + .projecao-v2-nota {
  margin: 9px 0 0;
}

/* O preview tem UMA tabela anual; o canônico tem DUAS (fase factual + carga por regime) e as mantém
   lado a lado quando cabe — a mesma decisão do ramo legado (`xl:grid-cols-2`). */
.projecao-v2-tabelas {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}
@media (max-width: 1180px) {
  .projecao-v2-tabelas {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* RELATÓRIOS --------------------------------------------------------------------------------- */

/* O `wave-card-heading` do preview põe um kicker ACIMA do h2; o canônico tem uma DESCRIÇÃO abaixo
   dele (copy canônica da seção "Relatórios rápidos"). */
.report-library > .wave-card-heading > div > p {
  margin: 4px 0 0;
  color: var(--muted);
  font-size: var(--fs-caption);
  line-height: 1.45;
}
/* O fato à direita do cabeçalho é a linha canônica "Última simulação: …" (um `<p>`, não um `<span>`
   como no preview) — mesma tipografia, sem quebrar. */
.report-library > .wave-card-heading > p {
  margin: 0;
  color: var(--muted);
  font-size: var(--fs-caption);
  text-align: right;
}

/* Estados canônicos (carregando · erro · nenhuma simulação) alojados no card da biblioteca — o
   preview só modela o caso com dado. */
.report-library > .relatorios-v2-corpo {
  padding: 0 14px 14px;
}

/* O canônico tem DUAS ações por card (o preview tem três: ele acrescenta "Imprimir", que aqui
   acontece dentro do painel aberto). Ausência permanece ausência: a linha volta a 2 colunas. */
.report-card-grid article > div:last-child:not(:has(> :nth-child(3))) {
  grid-template-columns: repeat(2, 1fr);
}
/* Link canônico D-247 dentro do card ("Ver a série completa em Projeções →"). Pós-H9 ele vive DENTRO
   do bloco de texto (depois do <small> da data) — sem esta regra ele sai inline, emendado no horário
   e no tamanho do parágrafo (achado da revalidação 04/08). Linha própria, tipografia de meta. */
.report-card-grid article .relatorios-v2-link-serie {
  display: block;
  margin-top: 6px;
  color: var(--muted);
  font-size: var(--fs-caption);
}
.report-card-grid article .relatorios-v2-link-serie:hover {
  color: var(--green);
}

/* Erro de geração e "nenhum cliente com análise salva" — estados canônicos do construtor; o preview
   só modela o caminho feliz. Ocupam a faixa inteira dos campos. */
.report-builder-fields > .relatorios-v2-erro,
.report-builder-fields > .relatorios-v2-sem-clientes {
  grid-column: 1 / -1;
  margin: 0;
  font-size: var(--fs-caption);
  line-height: 1.45;
}
.report-builder-fields > .relatorios-v2-erro {
  color: var(--yellow-deep);
}
.report-builder-fields > .relatorios-v2-sem-clientes {
  padding: 9px 10px;
  border: 1px dashed var(--line-strong);
  border-radius: 6px;
  color: var(--muted);
}
/* O botão "Gerar relatório" é o único filho de largura livre da grade de campos. */
.report-builder-fields > .button {
  grid-column: 1 / -1;
  justify-self: start;
}

/* IMPACTO DE RELEASE ------------------------------------------------------------------------- */

/* No preview o único parágrafo do cartão é o último; aqui o primeiro é o MOTIVO verbatim da porta e
   as releases ativas (bloco canônico) vêm depois — a regra `p:last-child` do preview não o alcança. */
.legal-gate-card > div > p:first-child {
  margin: 0;
  color: var(--muted);
  font-size: var(--fs-caption);
  line-height: 1.45;
}

/* "Quando isso muda": só a MOLDURA `legal-flow-card` é reaproveitada — as 4 caixas numeradas do
   preview (`legal-flow`) descreveriam um fluxo que o canônico não publica. */
.legal-flow-card > .impacto-v2-explicacao {
  margin: 0;
  color: var(--muted);
  font-size: var(--fs-caption);
  line-height: 1.5;
}
.legal-flow-card > .wave-card-heading {
  margin-bottom: 7px;
}
.legal-flow-card > .wave-card-heading .workspace-kicker {
  margin-bottom: 0;
}

/* A ação principal canônica ("Ver Consultas NCM / NBS") é um bloco próprio na pilha da rota. */
.impacto-v2-acao {
  display: flex;
}

/* ═════════════════════════════════════════════════════════════════════════════════════════════
 * CORREÇÕES DA AUDITORIA DE 04/08 (F3 · F4 · F6) — divergências DELIBERADAS da folha aprovada
 * ═════════════════════════════════════════════════════════════════════════════════════════════
 *
 * Estas três famílias de regra NÃO restauram o preview: elas o CONTRARIAM, de propósito, por ordem
 * expressa da rodada de correções ("texto ilegível não é aceito por fidelidade literal"). As folhas
 * `ui-v2-preview-compiled.css` e `ui-v2-home.css` continuam byte-intactas — o desvio mora aqui, é
 * nomeado e é reversível apagando este bloco.
 */

/* ── F6 · controles interativos: piso de legibilidade ─────────────────────────────────────────
 *
 * A folha aprovada dimensiona os controles do painel entre 5,8px e 8px. Isso é escala de MOCKUP: em
 * tela real, rótulo de campo, valor digitado e rótulo de botão ficam ilegíveis — e um formulário
 * fiscal que não se lê é risco de entrada errada, não só desconforto. Piso adotado:
 *   · texto de apoio/legenda de card ......... 10px
 *   · rótulo de campo, botão, aba, chip ...... 11px
 *   · valor DIGITADO (input/select) .......... 12px
 *
 * DECISÃO REGISTRADA sobre os 16px do iOS: o Safari do iPhone dá zoom automático ao focar um campo
 * com fonte < 16px. Levar TODOS os inputs a 16px estouraria as grades do preview (`.query-form-grid`
 * tem coluna de 165px; `.calendar-filter-card` empacota 7 colunas de `minmax(110px,1fr)`; os
 * controles têm 34–38px de altura) — quebraria o layout aprovado em todas as larguras para resolver
 * um comportamento de uma plataforma. Ficou 12px: legível no desktop e no Android, com o zoom do iOS
 * PERSISTINDO. Não é omissão, é escolha — e fica como pendência de UX mobile, não desta rodada.
 *
 * COBERTURA: só entram seletores com superfície REAL no app. A ordem citava ainda
 * `.wave-card-footer button`, `.simulation-fields input/select`, `.invoice-access-key` e
 * `.invoice-products-table` — nenhum deles é renderizado por componente algum (o rodapé de card, os
 * campos do wizard e o espelho DANFE são canônicos, com tipografia canônica). Overrides para eles
 * seriam CSS morto, então não foram escritos.
 */

/* Rótulos de campo (`<label><span>`) e legendas de fieldset das grades de formulário do preview. */
.query-form-grid label > span,
.service-context label > span,
.service-context legend,
.batch-upload-controls label > span,
.batch-mapping-grid label > span,
.calendar-filter-card label > span,
.projection-source-card label > span,
.report-builder-fields label > span,
.report-builder-fields legend,
.report-builder-fields fieldset label {
  font-size: var(--fs-label);
}

/* O VALOR digitado/escolhido — o texto que o usuário precisa conferir antes de simular. */
.query-form-grid input,
.query-form-grid select,
.service-context input,
.batch-upload-controls input,
.batch-upload-controls select,
.batch-mapping-grid select,
.calendar-filter-card select,
.calendar-filter-card input,
.projection-source-card select,
.report-builder-fields select {
  font-size: var(--fs-control);
}

/* Botões: os das grades de formulário, os das linhas de tarefa da Agenda, os dos cards de relatório,
   o "Limpar filtros" do calendário e as abas de modo da Central. */
.query-form-grid .button,
.batch-step .button,
.agenda-task-actions .button,
.report-card-grid .button,
.report-builder-fields .button,
.calendar-filter-card > button,
.query-mode-tabs button {
  font-size: var(--fs-button);
}

/* Legenda de apoio dentro do card de relatório (a linha que descreve o que o relatório entrega). */
.report-card-grid small {
  font-size: var(--fs-caption);
}

/* ── F4 · clipping horizontal entre 981px e ~1085px ───────────────────────────────────────────
 *
 * `.workspace-main` é `overflow: hidden` (folha aprovada). As duas grades de trabalho só colapsam em
 * ≤980px, mas entre 981 e 1180 elas ainda pedem larguras mínimas somadas de ~788px
 * (`.simulation-workspace-grid`: 300 + 470 + 18) e ~798px (`.calculator-layout`: 310 + 470 + 18).
 * Com a sidebar de 232px e o padding do main, a faixa útil cai abaixo disso por volta de 1080px — e
 * o excedente não vira barra de rolagem, vira conteúdo CORTADO. Antecipar o colapso para 1100px
 * (margem sobre o ponto medido) devolve a coluna única antes do corte.
 *
 * `.invoice-simulator-layout` NÃO entra: a própria folha aprovada já o colapsa em ≤1160px
 * (regra própria), então a NF-e nunca chega à faixa do defeito. */
@media (max-width: 1100px) {
  .simulation-workspace-grid,
  .calculator-layout {
    grid-template-columns: minmax(0, 1fr);
  }
  /* O cartão do formulário deixa de ser pegajoso junto com o colapso, como o preview faz em ≤980. */
  .calculator-form-card {
    position: static;
  }
}

/* ═════════════════════════════════════════════════════════════════════════════════════════════
 * RODADA DE CORREÇÃO VISUAL PÓS-ATIVAÇÃO (04/08) — G1..G11
 * ═════════════════════════════════════════════════════════════════════════════════════════════
 *
 * A flag mestra entrou em produção e a inspeção com dados REAIS achou defeitos que a validação
 * anterior não pegou: campos espremidos, grades colapsando na direção errada e texto de mockup
 * pequeno demais. Como no bloco F, as folhas aprovadas continuam byte-intactas — todo desvio mora
 * aqui, nomeado e reversível.
 */

/* ── G1 · pilhas V2 são de UMA coluna, sempre ────────────────────────────────────────────────
 *
 * `.workspace-rota-v2-stack`, `.carteira-v2-stack`, `.simulacao-v2-stack` e `.portfolio-view` são
 * PILHAS (`display: grid` só para reproduzir o espaçamento do `.workspace-content`). Um filho que
 * traga `grid-column: span N` — utilitário de coluna herdado do arranjo legado — faz o navegador
 * criar N-1 colunas implícitas e transforma a pilha numa grade multicoluna, com todos os blocos
 * comprimidos na 1ª trilha e as demais vazias. Foi exatamente o que quebrou `/projecao`. A causa
 * foi corrigida na origem (`ProjecaoClient`); esta regra é a rede: numa pilha de uma coluna,
 * `grid-column: 1` é o valor que já vale para todo mundo — só deixa de ser sobrescrevível. */
.workspace-rota-v2-stack > *,
.carteira-v2-stack > *,
.simulacao-v2-stack > *,
.portfolio-view > * {
  grid-column: 1;
}

/* ── G1.1 · a trilha dessas pilhas precisa ser DEFINIDA (é o congelamento do Monitor) ─────────
 *
 * ACHADO DE PERFORMANCE, prioridade máxima: alternar Lista ⇄ Monitor em `/carteira` congelava o
 * renderer por 20-60s. Não é `hidden` que falha, nem React: o ramo LEGADO monta as duas visões do
 * mesmo jeito (`MonitorGerencial` troca por `display:none`) e não congela.
 *
 * O que só existe no V2 são TRÊS invólucros `display: grid` empilhados sobre a mesma subárvore —
 * `.workspace-content` (folha aprovada), `.carteira-v2-stack` e `.portfolio-view` (bridge) — e
 * NENHUM declara `grid-template-columns`. Sem declaração, a trilha é implícita e `auto`: para
 * dimensioná-la o navegador precisa do min-content E do max-content de TUDO que está dentro, e
 * repete esse passe intrínseco nos três níveis. A subárvore revelada tem ~100 registros em duas
 * representações (tabela de 8 colunas com layout automático + cartões), sem virtualização.
 *
 * Pior: dentro dela vivem `container-type: inline-size` (`.cq-tabela-gerencial`, `.cq-cockpit`,
 * em `app/(workspace)/simulador/skin-v2.css`). Um container de tamanho inline NÃO contribui com o
 * próprio conteúdo para a própria largura — é o ponto do container query. Colocado dentro de uma
 * trilha `auto`, que só sabe se dimensionar PELO conteúdo, o navegador fica obrigado a fazer
 * passes extras de layout sobre a subárvore inteira até o `@container (min-width: 900px)`
 * estabilizar. É a multiplicação disso que vira meio minuto de tela travada.
 *
 * Uma trilha definida corta a raiz: `minmax(0, 1fr)` é EXATAMENTE o que uma pilha de uma coluna já
 * renderiza (largura do container, filhos autorizados a encolher), só que agora sem depender do
 * conteúdo para ser calculada. Zero diferença visual, e o `@container` passa a resolver com a
 * largura já conhecida, num passe só. */
.workspace-content,
.workspace-rota-v2-stack,
.carteira-v2-stack,
.simulacao-v2-stack,
.portfolio-view,
.calculator-dashboard,
.calculator-dashboard-v2 {
  grid-template-columns: minmax(0, 1fr);
}

/* ── G2 · `/simulador`: sem resultado não existe coluna de resultado ──────────────────────────
 *
 * `.calculator-layout` é `minmax(330px, .7fr) minmax(560px, 1.3fr)`: com o dashboard VAZIO (estado
 * inicial da rota — ausência permanece ausência), a metade direita da tela ficava em branco e o
 * formulário CANÔNICO era espremido em ~430px. E as grades internas do formulário canônico são
 * utilitários de BREAKPOINT (`sm:`/`lg:` medem a JANELA, não a coluna): a 1440px elas continuam
 * pedindo 3 colunas dentro de 430px — daí rótulos sobrepostos, selects de ~40px ("Selecio…"),
 * helpers com uma palavra por linha e o CTA quebrado em 4 linhas.
 *
 * É a MESMA mecânica que a rodada anterior já aplicou ao `.simulation-workspace-grid` e ao
 * `.invoice-simulator-layout` — e é por isso que `/simulador/servico` e `/simulador/nfe` saíram
 * perfeitos e `/simulador` não: `.calculator-layout` ficou de fora da família. */
.calculator-layout:not(:has(.calculator-dashboard > *)) {
  grid-template-columns: minmax(0, 1fr);
}
.calculator-layout:not(:has(.calculator-dashboard > *)) .calculator-dashboard {
  display: none;
}
/* Cartão pegajoso só faz sentido ao lado de uma coluna que rola; sozinho na faixa, não. Mesma
   decisão que a folha aprovada toma quando ela própria colapsa a grade (≤980px). */
.calculator-layout:not(:has(.calculator-dashboard > *)) .calculator-form-card {
  position: static;
}

/* ── U1 · `/simulador` é uma TRILHA, não duas colunas (UX-B1) ─────────────────────────────────
 *
 * A G2 acima colapsava a grade SÓ enquanto a coluna do dashboard estivesse vazia — e ela deixava de
 * estar vazia no CLIQUE, porque o "Calculando…" caía lá dentro. Efeito medido pela auditoria de
 * 17/08: numa janela de 1366px o formulário CANÔNICO era espremido para ~360-430px no instante em
 * que o contador mandava calcular, ainda sem resultado nenhum na tela.
 *
 * O pedido do Felipe (18/08, item 13) foi explícito — "não espremer o formulário para a esquerda;
 * montar uma trilha: preencher → resultado; uma linha de execução, não tudo na mesma tela". Então a
 * grade de duas colunas deixa de existir NESTA rota: `data-trilha` (escrito pelo `SimuladorV2` a
 * partir da decisão pura `decidirComposicaoTrilha`) marca a etapa e a grade passa a ter uma trilha
 * só, nos dois valores. Quem alterna não é a largura — é o CONTEÚDO de cada etapa: preenchendo, o
 * cartão do formulário ocupa a faixa e o dashboard fica sem filho; com resultado, o formulário vira
 * um resumo compacto e o dashboard ocupa a faixa inteira.
 *
 * A G2 permanece por cima como rede (mesma declaração, gatilho diferente) e continua valendo para
 * qualquer outra tela que use `.calculator-layout` sem `data-trilha`. */
.calculator-layout[data-trilha] {
  grid-template-columns: minmax(0, 1fr);
}
/* Sem coluna vizinha que role, não há o que "acompanhar": o cartão deixa de ser pegajoso, como a
   própria folha aprovada faz quando colapsa a grade em ≤980px. */
.calculator-layout[data-trilha] .calculator-form-card {
  position: static;
}

/* U2 · NF-e segue uma linha de execução; etapa de preencher e resultado nunca disputam colunas. */
.invoice-simulator-layout[data-trilha] {
  grid-template-columns: minmax(0, 1fr);
}

.invoice-simulator-layout[data-trilha] .simulation-form-panel {
  position: static;
}

/* ── G3 · cabeçalho do painel de prazos no tema escuro ───────────────────────────────────────
 *
 * `.deadlines-heading h2` divide a MESMA declaração de `.workspace-section-heading h2` na folha
 * aprovada (`color: var(--navy-950)`), mas o override de tema escuro que devolve `--ink` cita só o
 * segundo. `--navy-950` é token de marca (não muda por tema): #0a1724 sobre o painel escuro é
 * texto invisível. Mesmo valor que a folha já dá ao irmão — nenhuma cor nova. */
html[data-theme="dark"] .deadlines-heading h2 {
  color: var(--ink);
}

/* ── G4 · pílulas claras no tema escuro (defeito DO PRÓPRIO BRIDGE) ──────────────────────────
 *
 * Duas regras escritas nas rodadas anteriores deram `background: var(--white)` a um controle no
 * estado INATIVO — as abas de faceta do dossiê e os chips de próximos prazos do calendário.
 * `--white` é token fixo (#ffffff nos dois temas, como `--navy-950`), e a folha aprovada só o usa
 * junto de um override de escuro (`.dossier-tabs a.is-active` → `#102b3d`,
 * `.query-mode-tabs button.is-active` → `#102b3d`). Sem esse par, o resultado no escuro é uma
 * pílula BRANCA com texto `--muted` cinza-claro: ilegível.
 *
 * A folha aprovada, aliás, deixa o item INATIVO transparente e reserva a superfície clara para o
 * ATIVO — é isso que estas duas regras restauram. O estado ativo já era correto nos dois temas
 * (`--yellow-soft` é resolvido por tema) e não muda. */
html[data-theme="dark"] .dossier-tabs button:not(.is-active),
html[data-theme="dark"] .calendario-v2-proximos button:not(.is-active) {
  background: transparent;
  color: var(--ink-soft);
}

/* ── G5 · `.universe-switch` (filtro do calendário): segmento ativo branco no escuro ─────────
 *
 * Mesmo defeito de G4, desta vez na FOLHA aprovada: `.universe-switch button.is-active` recebe
 * `background: var(--white)` e `color: var(--ink)` e ficou de fora da lista de overrides de escuro
 * que a folha mantém para TODOS os irmãos do mesmo padrão (`.dossier-tabs a.is-active`,
 * `.import-mode-switch button.is-active`, `.query-mode-tabs button.is-active`, `.method-selector`,
 * `.refinement-mode-tabs`, `.companies-filters button.is-active`). Como o escopo padrão da rota é
 * `universo: "reais"`, o segmento ativo no load é sempre o PRIMEIRO — daí "o 1º segmento branco com
 * rótulo invisível". `#102b3d` é o valor que a própria folha usa nesse grupo. */
html[data-theme="dark"] .universe-switch button.is-active {
  background: #102b3d;
}
/* Piso F6: os botões do switch são NETOS do card (`.calendar-filter-card > .universe-switch >
   button`), então o override de controles escrito com combinador filho não os alcançava e eles
   ficaram nos 7px do mockup. Mesmo piso dos demais chips/abas. */
.universe-switch button {
  font-size: var(--fs-button);
}

/* ── G6 · `/carteira/destinos`: o tile "Sem destino" é um LINK ──────────────────────────────
 *
 * Os três tiles de cobertura têm o mesmo conteúdo (rótulo, contagem, detalhe, barra), mas só o
 * "Sem destino" é clicável (invariante D-230: a pendência de cobertura leva à tabela por
 * município). O `<a>` envolve o conteúdo, e com isso (a) vira o único item da grade do `article` —
 * e como âncora é `inline` por padrão, rótulo, número e detalhe colapsam num fluxo só, que foi o
 * "Sem destino4100,0%…" reportado; (b) empurra a barra para `article > a > i`, matando as três
 * regras de combinador FILHO que desenham a barra e a pintam de vermelho.
 *
 * Os dois problemas se resolvem devolvendo ao `<a>` a caixa que o `article` esperava e
 * re-endereçando as três regras — valores copiados literalmente da folha aprovada, nenhum novo. */
.coverage-segments article > a {
  display: grid;
  gap: 3px;
}
.coverage-segments article > a > i {
  height: 4px;
  overflow: hidden;
  margin-top: 3px;
  background: var(--line);
}
.coverage-segments article > a > i b {
  height: 100%;
  display: block;
}
.coverage-segments .is-missing > a > i b {
  background: #b6594e;
}

/* ── G7 · `/inicio`: a 8ª célula do grid de atalhos não é um card ────────────────────────────
 *
 * `.workspace-tool-grid` desenha os fios de 1px pintando o CONTAINER com `--line` e deixando cada
 * tile cobri-lo com `--white` — o fio é o `gap` que sobra. São 7 atalhos (curadoria D-255) numa
 * grade de 4 colunas: a 8ª célula não tem tile para cobrir e o fundo `--line` aparece em bloco,
 * lido como um card cinza vazio. No escuro é pior (`#304b5f` contra `#10283a`).
 *
 * A técnica é invertida sem mudar o resultado: o container deixa de pintar e cada tile projeta o
 * próprio fio de 1px. Os fios de tiles vizinhos ocupam o mesmo `gap` e continuam com 1px; a célula
 * sem tile passa a mostrar o painel atrás, que é o que "célula vazia" deve parecer. Vale para
 * qualquer contagem de colunas (a folha usa 4, 3, 2 e 1 conforme a largura). */
.workspace-tool-grid,
html[data-theme="dark"] .workspace-tool-grid {
  background: transparent;
}
.workspace-tool {
  box-shadow: 0 0 0 1px var(--line);
}
html[data-theme="dark"] .workspace-tool {
  box-shadow: 0 0 0 1px #304b5f;
}

/* ── G8 · `/relatorios`: a linha de ações do 3º card ─────────────────────────────────────────
 *
 * A folha aprovada endereça a linha de ações por `article > div:last-child` — no preview ela é
 * mesmo o último filho. No canônico, o card de Projeção ganha um 4º filho (o link D-247 "Ver a
 * série completa em Projeções →"), e aí `div:last-child` não casa com NADA: a linha de ações perde
 * `grid-column: 1 / -1` e `display: grid`, sobra na 2ª coluna estreita do cartão e os dois botões
 * empilham. Era por isso que só o 3º card destoava — e a regra que a rodada anterior escreveu
 * (`:not(:has(> :nth-child(3)))`) nunca chegava a ser avaliada nele.
 *
 * Re-endereçada pela POSIÇÃO real da linha (2º `div` do cartão: o 1º é o bloco de texto), com os
 * mesmos valores da folha e as 2 colunas que a rodada anterior já havia decidido — o canônico tem
 * duas ações por card, não as três do preview. */
.report-card-grid article > div:nth-of-type(2) {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 5px;
}

/* ── G9 · piso de legibilidade nas superfícies do WORKSPACE ──────────────────────────────────
 *
 * O bloco F6 aplicou o piso só aos CONTROLES de formulário. A inspeção em produção mostrou que o
 * problema é bem mais largo: a folha aprovada é um mockup em escala reduzida e ainda restam ~140
 * declarações VIVAS entre 5,5px e 9,5px — legendas de KPI, meta-linhas, cabeçalhos de tabela,
 * selos, rótulos de aba, descrições de card. Texto de 6px não é densidade, é texto que não se lê.
 *
 * Mesmos três degraus já registrados em F6, mais um para títulos pequenos de bloco:
 *   · legenda, apoio, meta, selo/badge ................ 10px
 *   · rótulo de controle, botão, aba, chip, tabela .... 11px
 *   · valor digitado e título pequeno de bloco ........ 12px
 *
 * COBERTURA — duas exclusões deliberadas, para não trocar o que já está aprovado e no ar:
 *  (a) HOME PÚBLICA e LOGIN (`.status-pill`, `.flow-step`, `.regime-list`, `.result-heading`,
 *      `.regime-row`, `.analysis-*`, `.report-section-label`, `.report-version`, `.report-table-*`,
 *      `.report-trace`, `.report-preview`, `.auth-snapshot-*`, `.footer-compact`, `.hero-audience`)
 *      ficam intocadas: são as duas superfícies que o Felipe já aprovou em produção, e esta rodada
 *      é sobre o ambiente logado. Entram como pendência de UX, não como correção silenciosa.
 *  (b) só entram seletores com superfície REAL — as ~270 classes do preview sem componente que as
 *      renderize (famílias `.admin-*`, `.support-*`, `.invoice-*`, `.simulation-fields`…) não
 *      recebem override, como em F6: CSS morto não é correção. */

/* 13px (--fs-caption) — legenda, texto de apoio, meta-linha (BeeDesign A1: piso informativo). */
.workspace-kicker,
.workspace-intro-compact .workspace-kicker,
.workspace-nav-group > span,
.workspace-sidebar-footer > span,
.workspace-tool > span,
.workspace-tool small,
.next-action li > span,
.next-action li small,
.wave-card-heading > span,
.wave-stat-grid span,
.wave-stat-grid small,
.action-queue a > span,
.action-queue a small,
.action-queue a > i,
.manager-kpis span,
.manager-kpis small,
.manager-card-heading > span,
.manager-insight,
.manager-insight span,
.deadline-item > strong small,
.deadline-item > div small,
.dossier-facts span,
.dossier-facts small,
.dossier-card-heading > span,
.competence-table th,
.competence-table td small,
.competence-panel-footer,
.competence-heading-status small,
.process-tabs a > span,
.process-tabs a i,
.import-mode-switch button span,
.import-side li > span,
.import-side li p,
.evolution-bars span,
.evolution-bars small,
.evolution-chart-card > p,
.wave-data-table th,
.wave-data-table code,
.mini-regime-text,
.regime-distribution-list span,
.regime-distribution-list strong,
.destination-origin-list dt,
.destination-origin-list dd,
.destination-filter p,
.coverage-segments span,
.coverage-segments small,
.mix-list span,
.calendar-month-card > p,
.agenda-view-tabs button span,
.agenda-task-origin span,
.agenda-task-origin strong,
.agenda-task-main p,
.agenda-task-main small,
.query-domain-tabs small,
.query-result-state p,
.service-context summary small,
.service-context > p,
.service-context label small,
.service-context fieldset > small,
.batch-step > span,
.batch-step p,
.batch-step h2 small,
.batch-mapping-grid label small,
.batch-step > div > small,
.projection-tracks i span,
.projection-source-card > div span,
.projection-rows > div > small,
.projection-legend span,
.report-card-grid p,
.report-card-grid article > span,
.report-output-types span,
.full-report-intro p:not(.workspace-kicker),
.legal-gate-card p:last-child,
.calculator-text-copilot header p,
.calculator-text-copilot header b,
.calculator-text-copilot > p,
.calculator-text-copilot > small,
.calculation-memory summary span,
.decision-summary-main > div > span,
.decision-summary-main > div > a {
  font-size: var(--fs-caption);
}

/* Selo/badge de ESTADO — único papel autorizado a ficar em 11px (--fs-badge). */
.calculation-status,
.count-badge,
.legal-gate-badge,
.regime-verdict-badge,
.regime-verdict-badge.is-compact,
.state-label {
  font-size: var(--fs-badge);
  font-weight: 600;
}

/* EXCEÇÃO DECORATIVA (A1): numeração 01..N da sidebar V2 — `<i aria-hidden="true">`, sem informação
   (WorkspaceShellV2.tsx). Pode ficar no tamanho de badge. */
.workspace-nav-group a i {
  font-size: var(--fs-badge);
}

/* 14px (--fs-button) — botão, aba, chip clicável. */
.module-heading-actions .button,
.dossier-action-row .button,
.dossier-tabs a,
.agenda-view-tabs button,
.query-domain-tabs button > span,
.competence-panel-footer button,
.manager-card-heading > a {
  font-size: var(--fs-button);
}

/* 14px (--fs-label) — rótulo de controle. */
.destination-filter label span,
.service-context fieldset label,
.calculator-text-copilot > label {
  font-size: var(--fs-label);
}

/* 14px (--fs-body-2) — corpo de tabela e dado conferido. */
.agenda-task-main > strong,
.process-tabs a strong,
.import-mode-switch button strong,
.import-side li strong,
.competence-table,
.wave-data-table,
.decision-summary-main > div p,
.projection-source-card > div strong,
.projection-rows > div > strong {
  font-size: var(--fs-body-2);
}

/* 15px (--fs-control) — valor digitado. */
.competence-toolbar input,
.import-card input,
.import-card select,
.destination-filter select,
.calculator-text-copilot textarea {
  font-size: var(--fs-control);
}

/* 16px (--fs-card-title) — título pequeno de bloco. */
.calculator-document-reader h3,
.calculator-text-copilot h3,
.query-result-state h3,
.report-card-grid h3 {
  font-size: var(--fs-card-title);
}

/* 14px (--fs-body-2) — resumo/aba. */
.calculation-memory summary,
.query-domain-tabs strong {
  font-size: var(--fs-body-2);
}

/* ── G10 · fato fiscal não é chip: parar de cortar valor no meio ─────────────────────────────
 *
 * `.projection-source-card > div strong` carrega o critério visível da rota ("Projeção de: X") e a
 * folha o trata como chip: `white-space: nowrap` + reticências. Com o texto real — nome de cliente,
 * "Último PGDAS importado…", valores — o que sobra na tela é um fato cortado, que é pior do que
 * duas linhas. A coluna é de largura flexível; deixar quebrar não desloca nada ao lado. */
.projection-source-card > div strong {
  overflow: visible;
  white-space: normal;
}

/* ── G11 · `/carteira` Monitor: a tabela por cliente cabe em vez de rolar por dentro ─────────
 *
 * A tabela gerencial só aparece quando o CONTAINER passa de 900px (`@container tabela-gerencial`,
 * `app/(workspace)/simulador/skin-v2.css`) — abaixo disso vira cartões. O limiar foi medido, mas
 * contra cabeçalhos que não quebram: as 8 colunas têm `white-space: nowrap`, e só os títulos
 * ("Faturamento anual", "Melhor regime projetado"…) já somam perto de 900px. Com o conteúdo real
 * a soma passa da faixa e a última coluna sai pela direita, atrás de uma barra de rolagem interna
 * — que o próprio componente documenta como "rede de segurança extrema, não a experiência".
 *
 * Deixar o TÍTULO quebrar em duas linhas devolve ~160px à tabela e ela volta a caber inteira na
 * faixa em que o container query já a autoriza. Nenhuma coluna sai, nenhum limiar muda, o modo
 * cartão continua valendo abaixo de 900px. O `html` no seletor é só para vencer a utilitária de
 * `nowrap` independentemente da ordem em que as folhas chegam ao `<head>`. */
html [data-skin="v2"] .cq-tabela-completa thead th {
  white-space: normal;
}

/* Mesma família de defeito, dentro da célula: o selo de "melhor regime projetado" trunca com
   reticências num `max-width` fixo, e o que sobra na tela é meia palavra ("cClassTrib (classe
   direta"). O `max-width` continua limitando a coluna; só o corte vira quebra de linha — num
   monitor fiscal, meia informação é pior que duas linhas. */
html [data-skin="v2"] .cq-tabela-completa td .truncate,
html [data-skin="v2"] .cq-tabela-cards .truncate {
  overflow: visible;
  white-space: normal;
  text-overflow: clip;
}

/* ═════════════════════════════════════════════════════════════════════════════════════════════
 * RODADA DE REFINAMENTO VISUAL (04/08) — H1..H13
 * ═════════════════════════════════════════════════════════════════════════════════════════════
 *
 * A rodada anterior (G1..G11) devolveu a legibilidade; esta trata a UNIFORMIDADE. Três famílias:
 * (i) o formulário do `/simulador`, que continuava medindo a JANELA em vez da coluna onde caiu
 * (P-162); (ii) tratamentos que divergiam de rota para rota (canvas, seleção, fecho de página);
 * (iii) os restos do catálogo v2. Como sempre, as folhas aprovadas seguem byte-intactas: todo desvio
 * mora aqui, nomeado e reversível apagando o bloco.
 */

/* ── H1 · `position: sticky` volta a existir dentro do cromo V2 ───────────────────────────────
 *
 * `.workspace-main` é `overflow: hidden` (folha aprovada, 5188). Isso não só corta o excedente: faz
 * do `main` um SCROLLPORT. Como `position: sticky` se resolve contra o scrollport mais próximo, e
 * esse scrollport nunca rola (quem rola é o documento), TODO sticky de dentro do workspace vira
 * estático — inclusive os três que o produto declara de propósito: `.calculator-form-card`
 * (`top: 82px`, folha aprovada), o trilho do formulário do simulador (`lg:sticky lg:top-6`,
 * canônico) e o CTA de rodapé do mobile (`sticky bottom-0 … lg:static`, UXA-013).
 *
 * É a metade que faltava do defeito "coluna morta": o trilho não acompanhava porque não PODIA
 * acompanhar. `overflow: clip` corta exatamente igual a `hidden` — mesma caixa, mesmo recorte — mas
 * NÃO cria scrollport, então o sticky volta a se resolver contra a viewport. Nenhuma outra
 * diferença: `clip` só remove a capacidade (nunca usada) de rolar o `main` programaticamente. */
.workspace-main {
  overflow: clip;
}

/* ── H2 · o formulário do `/simulador` passa a medir o CONTAINER (raiz da P-162) ──────────────
 *
 * O `FormularioSimulacao` canônico divide-se em `lg:grid-cols-12` → coluna principal `lg:col-span-8`
 * + trilho `lg:col-span-4`, e as grades de campo internas usam `sm:`/`lg:`. TODAS essas utilitárias
 * medem a JANELA. O formulário, porém, cai em contextos de largura muito diferente:
 *
 *   · sem resultado (G2 colapsou a grade) ....... cartão em ~1090px  → 8/4 faz sentido
 *   · com resultado (`.calculator-layout` .7fr) . cartão em ~390px   → 8/4 vira 285px/143px
 *
 * A 1440px de janela o `lg:` está ativo NOS DOIS casos — daí "3 colunas dentro de 430px", selects de
 * ~40px e helpers com uma palavra por linha. Foi o item que a rodada anterior registrou como "fora
 * desta rodada" por falta de autorização para tocar o componente; a autorização veio (exceção
 * nominal: SÓ classes de layout) e a raiz é corrigida aqui.
 *
 * O cartão vira um CONTAINER (`bf-form`) e o formulário passa a se arranjar pela largura REAL:
 *  · container < 1040px → uma coluna, largura total — o mesmo arranjo das telas irmãs
 *    (`/simulador/operacao`, `/servico`, `/nfe`), que é a referência boa;
 *  · (F4a, 12/10: o ramo "container ≥ 1040px → duas colunas com trilho sticky" foi REMOVIDO junto com o
 *    trilho; agora é uma coluna única em qualquer largura.)
 *
 * As grades de campo internas ganham o mesmo tratamento, sempre para BAIXO (nunca criam colunas que
 * a utilitária não pediu): abaixo de 640px de container tudo vira uma coluna; entre 640 e 1023 o que
 * pedia 3 ou 4 colunas fica em 2. `grid-column: auto` é obrigatório junto — numa grade de uma coluna,
 * um `col-span-2` remanescente fabricaria colunas implícitas (é a mecânica da ALTA 2 da rodada G). */
.calculator-form-card {
  container-type: inline-size;
  container-name: bf-form;
}

[data-skin="v2"] .simulador-form-grade {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
  gap: 16px;
}
[data-skin="v2"] .simulador-form-coluna {
  grid-column: 1;
}
/* F4a (12/10): o trilho direito saiu do formulário (e com ele as regras `.simulador-form-trilho`,
 * `.simulador-painel-simples*` e a grade de 2 colunas em container de 1040px ou mais, incluindo a
 * decisão E3·C2 "painel esticado na altura toda", REVOGADA pelo Felipe em 12/10). O formulário é coluna
 * única, na largura toda, em qualquer container; o enquadramento do Simples é a faixa `.simulador-faixa-simples`
 * (bloco "F4a-E", antes do bloco C4 deste arquivo). */

@container bf-form (max-width: 639px) {
  [data-skin="v2"] .calculator-form-card .grid {
    grid-template-columns: minmax(0, 1fr);
  }
  [data-skin="v2"] .calculator-form-card .grid > * {
    grid-column: auto;
  }
}

@container bf-form (min-width: 640px) and (max-width: 1023px) {
  [data-skin="v2"] .calculator-form-card .grid.lg\:grid-cols-3,
  [data-skin="v2"] .calculator-form-card .grid.lg\:grid-cols-4 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}


/* ── H3 · a linha de rótulo VAZIA do `<Selecionar label="">` não reserva altura ────────────────
 *
 * `<Selecionar>` reserva `min-height: 2.9rem` para a linha do rótulo — é o que mantém os campos de
 * uma mesma linha da grade alinhados quando um rótulo quebra em duas. Quando o chamador passa
 * `label=""` (porque desenha um rótulo EXTERNO próprio), essa linha continua existindo, agora VAZIA,
 * e some 46px de vão morto entre o rótulo externo e o select. A regra abaixo zera a reserva
 * exatamente nesse caso (`label:empty` só acontece com `label=""` passado de propósito).
 *
 * ALCANCE, atualizado na onda UX-B1 (smoke Felipe 18/08, item 2): o call-site vivo desta regra é
 * "Enquadramento de serviços no Simples" (`FormularioSimulacao`, bloco ③), que mantém rótulo externo
 * porque tem um parágrafo de apoio ENTRE o rótulo e o select. A segunda metade desta correção — um
 * `min-height` compensatório no rótulo externo de `.simulador-linha-empresa` — FOI REMOVIDA porque o
 * defeito que ela reconciliava deixou de existir na fonte: "Atividade com tributação específica"
 * voltou a ser um `<Selecionar>` com rótulo próprio (`tooltip` agora é prop do componente), então os
 * três campos daquela linha compartilham literalmente o mesmo nó de reserva de altura e alinham por
 * construção, em qualquer largura — inclusive quando um rótulo quebra em três linhas, que era o caso
 * em que a compensação por CSS ainda falhava. */
[data-skin="v2"] .calculator-form-card div:has(> label:empty) {
  min-height: 0;
}

/* ── H4 · helpers deixam de ser espremidos em 3-4 linhas ──────────────────────────────────────
 *
 * Duas linhas da seção "② Dados essenciais" pediam trilhas iguais para campos de peso muito
 * diferente:
 *
 *  · "Atividade | Regime atual | Ativ. específica": em 4 trilhas iguais (a 3ª ocupa 2), o helper do
 *    "Regime atual" — a frase mais longa do formulário — caía em ~265px e quebrava em 3-4 linhas,
 *    enquanto "Atividade" (sem helper) desperdiçava a mesma largura. Trilhas proporcionais devolvem
 *    ~375px ao helper (2 linhas) e mantêm "Ativ. específica" como a MAIS larga das três, que é o que
 *    a D-257/Onda 3 decidiu ao alargá-la.
 *
 *  · "CNPJ | CNAE | DAS do Simples": o 3º campo só existe quando o regime atual É Simples. Fora
 *    disso, dois campos ficavam numa grade de três trilhas fixas e sobrava um vão morto de ~310px à
 *    direita. `auto-fit` resolve pelo número REAL de campos: 3 quando o DAS aparece, 2 dividindo a
 *    faixa inteira quando não aparece. Nenhum campo, nome ou ordem muda — só a trilha. */
@container bf-form (min-width: 1040px) {
  [data-skin="v2"] .simulador-linha-empresa {
    /* Ajuste fino da revalidação 04/08: o helper do "Regime atual" (coluna 2) quebrava em 3 linhas
       com 1.25fr; a coluna 2 ganha o excedente da 3 (helpers das duas ficam em ≤2 linhas). */
    grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.4fr) minmax(0, 1.25fr);
  }
  [data-skin="v2"] .simulador-linha-empresa > * {
    grid-column: auto;
  }
}
@container bf-form (min-width: 640px) {
  [data-skin="v2"] .simulador-linha-cnpj {
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  }
}

/* ── H5 · UM canvas: `--paper-deep` deixa de ser creme ────────────────────────────────────────
 *
 * O relato foi "`/relatorios` amarelado, `/agenda` e `/carteira/documentos` esverdeados, o resto
 * branco". A causa não é de rota nenhuma: é um TOKEN. No tema claro padrão a folha aprovada declara
 * `--paper-deep: #ebeeda` (linha 274) — R235 G238 B218, um creme/oliva. Esse token é o fundo de
 * quase toda superfície "poço" do preview: `.dossier-tabs`, `.process-tabs`, `.agenda-view-tabs`,
 * `.query-domain-tabs`, `.universe-switch`, `.import-mode-switch`, `.deadlines-panel`,
 * `.companies-toolbar`, `.issue-list article`, `.comparison-cards article`, `.collection-grid
 * article`, `.certificate-*`, `.projection-tracks i`… Quanto mais poço uma rota tem, mais a página
 * inteira puxa para o amarelo-esverdeado — e as rotas feitas de cartão branco ficam brancas. Daí
 * três canvas diferentes sem que ninguém tenha escrito uma cor por rota.
 *
 * O valor adotado NÃO é inventado: é o que a PRÓPRIA folha aprovada declara para esse mesmo token na
 * variante de alto contraste do tema claro (`html[data-contrast="high"]`, linha 1968) — `#eef1f2`,
 * um cinza neutro da mesma família. Um token, uma linha, reversível; o tema escuro já era neutro
 * (`#132939`) e não muda. Este é o "UM canvas" da ordem: o poço passa a ser neutro em toda rota, e a
 * cor volta a significar estado (âmbar = atenção, verde = confirmado), não decoração de fundo. */
:root {
  --paper-deep: #eef1f2;
}

/* ── H6 · UMA linguagem de seleção ────────────────────────────────────────────────────────────
 *
 * A folha aprovada tem oito controles que dizem "qual visão/modo está selecionado", em três
 * dialetos:
 *   (A) trilho `--paper-deep` + ativo em superfície CLARA .... `.dossier-tabs`, `.query-mode-tabs`,
 *       `.universe-switch`, `.import-mode-switch`  →  QUATRO ocorrências: é a família DOMINANTE;
 *   (B) trilho `--paper-deep` + ativo NAVY sólido ............ `.agenda-view-tabs`,
 *       `.query-domain-tabs` (a "aba navy saliente" da `/classificacao`), `.process-tabs`;
 *   (C) sublinhado verde ..................................... (era o toggle Lista|Monitor, removido no B2).
 *
 * Escolha registrada: (A) — a família mais frequente da própria folha, e a única que já vem com par
 * de tema escuro escrito pelos autores (`#102b3d`). (B) e (C) convergem para ela com os MESMOS
 * valores que (A) usa; nenhuma cor nova entra. O que NÃO muda: badge de ESTADO continua semântico —
 * a contagem âmbar da `.agenda-view-tabs`/`.process-tabs` e o `--line` do inativo ficam como estão,
 * porque ali a cor informa, não seleciona. */
.agenda-view-tabs button.is-active,
.query-domain-tabs button.is-active,
.process-tabs a.is-active {
  background: var(--white);
  color: var(--navy-950);
  box-shadow: 0 4px 12px rgba(10, 23, 36, 0.08);
}
html[data-theme="dark"] .agenda-view-tabs button.is-active,
html[data-theme="dark"] .query-domain-tabs button.is-active,
html[data-theme="dark"] .process-tabs a.is-active {
  background: #102b3d;
  color: var(--ink);
}
/* O contador da aba ativa continua âmbar (estado), agora sobre superfície clara. */
.agenda-view-tabs button.is-active span,
.process-tabs a.is-active i {
  background: var(--yellow);
  color: var(--navy-950);
}

/* ── H7 · UM fecho de página ──────────────────────────────────────────────────────────────────
 *
 * Três tratamentos conviviam: o rodapé de nota do `/simulador`, `/inicio` e `/carteira/importar`
 * (`<footer>` com filete e texto centrado, classes canônicas), a nota final da `/projecao` (parágrafo
 * solto, sem filete) e nada nas demais. Rota logada não tem rodapé legal (P-747); o `RodapeLegal`
 * (D-232) fecha só as páginas públicas — estas notas são o fecho da página logada.
 *
 * Padrão único adotado = o do `<footer>` (o mais frequente, e o único que já separa a nota do corpo
 * com um filete): filete de 1px em `--line`, texto centrado em `--muted`, 11px, com o mesmo respiro
 * acima. A nota da `/projecao` passa a usá-lo. Nenhuma rota GANHA uma nota que não tinha: ausência
 * de nota de honestidade continua sendo ausência. */
.workspace-content footer.border-t,
[data-skin="v2"] .projection-chart-card > .projecao-v2-nota:last-child {
  margin-top: 28px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
  color: var(--muted);
  text-align: center;
  font-size: var(--fs-caption);
  line-height: 1.5;
}

/* ── H8 · `/inicio`: o fio órfão da 8ª célula ─────────────────────────────────────────────────
 *
 * A G7 já tirou o BLOCO cinza (o container deixou de pintar o fundo e cada tile passou a projetar o
 * próprio fio de 1px). Sobrou o FIO: o último tile da 2ª fileira ainda projeta a sombra da sua borda
 * direita para dentro da célula vazia — um divisor que não separa nada. Com 7 atalhos (curadoria
 * D-255) numa grade de 4 colunas isso é permanente.
 *
 * RETRATADA na revalidação de 04/08: `grid-column-end: -1` com início automático tem span 1 — o
 * último tile PULAVA para a última coluna e deixava um buraco no MEIO da fileira (pior que o fio).
 * Com a G7 (cada tile projeta o próprio fio fechado), a célula vazia ao FIM da fileira já lê como
 * "painel vazio" natural — nenhuma regra extra é necessária. */

/* ── H9 · `/relatorios`: os três cards fecham na mesma linha de base ──────────────────────────
 *
 * `.report-card-grid article` é uma grade de `31px + 1fr` com linhas automáticas, e linhas `auto`
 * esticam para preencher o cartão (`align-content: normal` = `stretch`). Com textos de comprimentos
 * diferentes — e com o 3º cartão carregando um filho a mais, o link D-247 "Ver a série completa em
 * Projeções →" — a fileira de botões parava numa altura diferente em cada cartão.
 *
 * A correção tem duas metades. Aqui: a 1ª linha (ícone + texto) absorve toda a folga (`1fr`) e a
 * linha de ações fica ancorada embaixo (`auto`), igual nos três. No componente
 * (`CardRelatorioV2`): o link D-247 passa a fechar o BLOCO DE TEXTO em vez de virar uma 4ª linha do
 * cartão — ele continua exatamente onde estava na leitura (logo abaixo da descrição/data), o link
 * permanece intacto, e os três cartões voltam a ter a mesma estrutura de duas linhas. */
.report-card-grid article {
  grid-template-rows: 1fr auto;
}

/* ── H10 · `/projecao`: o valor sai de cima da barra ──────────────────────────────────────────
 *
 * A folha desenha o rótulo DENTRO da barra (`.projection-tracks i span` é `position: absolute;
 * inset: 0 4px`) com 5,5px — cabia porque era ilegível. Com o piso de legibilidade da G9 (10px) o
 * texto passou a montar sobre a faixa dourada, que tem 9px de altura.
 *
 * O rótulo passa a viver À DIREITA da barra: a barra reserva a faixa do rótulo com `margin-right`, o
 * `span` é reposicionado a partir do fim dela (`left: 100%`) e o `overflow` do trilho deixa de
 * recortá-lo. A barra segue com a mesma mecânica de preenchimento (`b` com `width: X%` sobre o
 * trilho), só um pouco mais alta para acompanhar a tipografia legível. Nenhum valor novo, nenhuma
 * série nova — só o rótulo fora da barra, que é o que a ordem pediu. */
[data-skin="v2"] .projection-tracks i {
  height: 12px;
  margin-right: 96px;
  overflow: visible;
  border-radius: 3px;
}
[data-skin="v2"] .projection-tracks i b {
  border-radius: 3px;
}
[data-skin="v2"] .projection-tracks i span {
  inset: 0 auto 0 100%;
  width: 96px;
  padding-left: 8px;
  justify-content: flex-start;
  color: var(--muted);
  white-space: nowrap;
}

/* ── H11 · `/carteira/destinos`: filtro sem conteúdo não desenha barra ────────────────────────
 *
 * `.destination-filter` é um cartão branco com borda e padding, e a rota o renderiza sempre — mesmo
 * quando o filtro canônico de UF não tem o que oferecer. O que aparecia antes da tabela "Por UF" era
 * a moldura vazia dele: uma faixa branca órfã. Ausência permanece ausência também na moldura. */
.destination-filter:not(:has(*)) {
  display: none;
}

/* ── H12 · `/carteira/documentos`: o rótulo encostava na busca ────────────────────────────────
 *
 * `.competence-toolbar` é `display: flex; align-items: center` e o formulário de busca canônico traz
 * rótulo em cima do campo. Centralizado, o par rótulo+campo ficava colado no que estivesse ao lado e
 * desalinhado da linha do botão. Alinhar pela BASE (`end`) é o que a própria folha faz na barra
 * equivalente da `/carteira/destinos` (`.destination-filter { align-items: end }`) — mesmo padrão,
 * mesmo valor — e o respiro entre rótulo e campo vem do `gap` que a folha já usa lá (4px). */
.competence-toolbar {
  align-items: end;
}
.competence-toolbar label {
  display: grid;
  gap: 4px;
}

/* ── H13 · esqueleto de carregamento: pulso vira shimmer ──────────────────────────────────────
 *
 * Percepção pura, sem tocar dado nem carregamento (a ordem separou isso da rodada de performance).
 * Os esqueletos canônicos usam `animate-pulse` — o bloco inteiro pisca em opacidade, o que a essa
 * altura o olho lê como "travou". Um shimmer varrendo o bloco lê como "está vindo", e é o que a
 * troca de faceta do dossiê precisa enquanto o servidor responde.
 *
 * Escopo: só dentro do cromo V2 (esta folha só é injetada com a flag mestra ligada) e só onde o
 * canônico já declarou um esqueleto. `prefers-reduced-motion` desliga a animação e devolve uma
 * superfície estática — nunca um bloco piscando para quem pediu menos movimento. */
@keyframes bf-v2-shimmer {
  from { background-position: 180% 0; }
  to { background-position: -80% 0; }
}
.workspace-content .animate-pulse {
  animation: bf-v2-shimmer 1.35s linear infinite;
  background-image: linear-gradient(
    100deg,
    transparent 20%,
    rgba(255, 255, 255, 0.55) 44%,
    transparent 68%
  );
  background-repeat: no-repeat;
  background-size: 180% 100%;
  opacity: 1;
}
html[data-theme="dark"] .workspace-content .animate-pulse {
  background-image: linear-gradient(
    100deg,
    transparent 20%,
    rgba(255, 255, 255, 0.08) 44%,
    transparent 68%
  );
}
@media (prefers-reduced-motion: reduce) {
  .workspace-content .animate-pulse {
    animation: none;
    background-image: none;
  }
}

/* ── P163-1 · o dashboard de resultado mede o CONTAINER (mesma raiz da H2) ────────────────────
 *
 * O dashboard de resultado (`.calculator-dashboard-v2`) cai em contextos de largura muito
 * diferentes — a coluna `.7fr` da `.calculator-layout` mediu 798px com a JANELA em 1440px — e as
 * grades internas usam utilitárias que medem a janela: a `LinhaKpiResultado` abre `lg:grid-cols-4`
 * (tiles de 190px; `R$ 1.024.320,00` mede 196px e sangra sobre o vizinho) e os cards da
 * `ComparacaoRegimes` abrem `lg:grid-cols-3` (cards de ~250px; o valor imprime sobre "Alíquota
 * efetiva"). Mesma mecânica da P-162/H2, mesmo remédio: o dashboard vira container `bf-dashboard`
 * e as grades passam a se arranjar pela largura REAL, sempre para BAIXO (a query só reduz colunas
 * que a utilitária pediu, nunca cria). `grid-column: auto` acompanha toda redução a 1 coluna
 * (mecânica da ALTA 2 da rodada G).
 *
 * Limiares por geometria dos CONTEÚDOS (validação visual na própria rodada):
 *  · KPI: chip 40px + gap 12px + valor 196px + padding/borda 34px ≈ 282px/tile ⇒ 4 colunas só
 *    com ≥1140px de container; 2 colunas até 560px; abaixo, 1.
 *  · Cards de regime: o par interno "Carga total | Alíquota efetiva" (`grid-cols-2`) precisa de
 *    ~380px de card ⇒ 3 colunas só com ≥1180px de container; 2 colunas até 680px; abaixo, 1.
 *    Nas faixas em que o card fica com <380px (2 colunas entre 680-789px de container; 1 coluna
 *    com container <430px), o par interno empilha. */
.calculator-dashboard-v2 {
  container-type: inline-size;
  container-name: bf-dashboard;
}

@container bf-dashboard (max-width: 1139px) {
  [data-skin="v2"] .calculator-dashboard-v2 .grid.lg\:grid-cols-4 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@container bf-dashboard (max-width: 559px) {
  [data-skin="v2"] .calculator-dashboard-v2 .grid.lg\:grid-cols-4 {
    grid-template-columns: minmax(0, 1fr);
  }
  [data-skin="v2"] .calculator-dashboard-v2 .grid.lg\:grid-cols-4 > * {
    grid-column: auto;
  }
}

@container bf-dashboard (max-width: 1179px) {
  [data-skin="v2"] .calculator-dashboard-v2 .grid.lg\:grid-cols-3 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@container bf-dashboard (max-width: 679px) {
  [data-skin="v2"] .calculator-dashboard-v2 .grid.lg\:grid-cols-3 {
    grid-template-columns: minmax(0, 1fr);
  }
  [data-skin="v2"] .calculator-dashboard-v2 .grid.lg\:grid-cols-3 > * {
    grid-column: auto;
  }
}

@container bf-dashboard (min-width: 680px) and (max-width: 789px) {
  [data-skin="v2"] .calculator-dashboard-v2 article .grid.grid-cols-2 {
    grid-template-columns: minmax(0, 1fr);
  }
}
@container bf-dashboard (max-width: 429px) {
  [data-skin="v2"] .calculator-dashboard-v2 article .grid.grid-cols-2 {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ── P163-4 · `/classificacao`: o seletor 01/02 ganha o acento (ordem Felipe 05/08) ───────────
 *
 * "Aqui vale cor de destaque para direcionar usuário" — gate ao vivo. A H6 unificou a seleção na
 * família A (ativo em superfície clara + sombra), mas no `.query-domain-tabs` — a ESCOLHA-MÃE da
 * tela (Produtos × Serviços) — branco-sobre-cinza tem salência baixa demais para uma bifurcação.
 * O ativo soma um anel interno no âmbar da pele (`--yellow`, token existente — nenhuma cor nova):
 * acento de DIREÇÃO, não de estado; badge semântico continua com o papel de sempre. */
.query-domain-tabs button.is-active {
  box-shadow: 0 4px 12px rgba(10, 23, 36, 0.08), inset 0 0 0 2px var(--yellow);
}
html[data-theme="dark"] .query-domain-tabs button.is-active {
  box-shadow: inset 0 0 0 2px var(--yellow);
}

/* ── P163-5 · Dossiê da empresa: os NÚMEROS voltam a ser a informação (ordem Felipe 05/08) ────
 *
 * "Discrepância de tamanho de fontes" — gate ao vivo, medido: os valores dos fatos (7 · 1 · 0 ·
 * 12) saíam a 13px — MENORES que o parágrafo comum (15px) — enquanto o h1 (36px, correto: é o
 * mesmo clamp dos títulos de módulo) dominava sozinho. Num painel de fatos, o número É a
 * informação: sobe para 20px (degrau entre o corpo 15px e o h2 17px→acima), rótulos ficam no piso
 * G9. O badge do certificado (span próprio) não herda o salto. */
.dossier-facts strong {
  font-size: 20px;
  line-height: 1.2;
}

/* ── J1 · a trilha do `.workspace-stage` precisa ser DEFINIDA (FIX-J · R-2026-09-04) ───────────
 *
 * Mesma raiz da G1.1, um nível acima. `.workspace-stage` (folha aprovada, 4934) é `display: grid`
 * com `grid-template-rows: auto 1fr auto` e NENHUMA coluna declarada — a coluna é implícita e
 * `auto`, dimensionada pelo conteúdo. Numa trilha `auto` a base é a maior contribuição de
 * min-content entre os itens, e a `.workspace-topbar` (flex, nowrap, `min-width: auto`) contribui
 * com a soma dos filhos: padding 32 + drawer 42 + gaps 16 + contexto de empresa 292 (o chip
 * canônico `ClienteContexto` é `truncate`, logo nowrap: "Nenhuma empresa selecionada" inteira) +
 * controles 132 = 514px. A 390px de viewport a coluna vira 514px, `header` E `main` medem 514px e
 * o documento rola 124px na horizontal — em `/carteira` e em `/carteira/cliente/<id>` igualmente
 * (o conteúdo do `main` não participa: escondê-lo não muda a medida; esconder o topbar, sim).
 * Medido em produção (job 349, `15c84490`) com sessão real em 390×844, light e dark, e reproduzido
 * no build local com `UI_V2_WORKSPACE_LIGADA=true`.
 *
 * O `min-w-0` do slot de contexto autoriza o chip a ENCOLHER no layout, mas não reduz a contribuição
 * de min-content do topbar para a trilha — por isso a Design Closure (que mexeu nas @container do
 * Monitor) não podia fechar este resíduo: a raiz não está no conteúdo, está no cromo.
 *
 * `minmax(0, 1fr)` é o que a coluna única já renderiza em qualquer largura onde o cromo cabe (a
 * largura do container), só que agora sem depender do conteúdo. Com a trilha em 390px o topbar volta
 * a ser flex de verdade: o slot `min-w-0 flex-1` encolhe e o chip trunca com reticências, como foi
 * desenhado. Nenhum `overflow-x: hidden` global: nada é escondido, o excedente deixa de existir.
 * Desktop não muda (a coluna já ocupava o container inteiro). Alcance exato: prova as duas rotas
 * sentinela em 390px e 1440px, nos dois temas, com a carteira do Felipe — não prova outras larguras
 * nem outros chips de contexto. */
.workspace-stage {
  grid-template-columns: minmax(0, 1fr);
}

/* ── F3 · impressão ───────────────────────────────────────────────────────────────────────────
 *
 * O `@media print` canônico (`globals.css`) foi escrito para o cromo LEGADO: ele esconde `aside` e
 * `header` inteiros e zera o `<main>`. Sob o cromo V2 isso produz três defeitos:
 *   (a) `.workspace-shell` continua sendo uma grade de `248px + conteúdo` — com a sidebar oculta, a
 *       primeira coluna some visualmente mas a TRILHA da grade permanece, e o conteúdo imprime
 *       espremido na faixa da direita;
 *   (b) `header { display: none !important }` derruba TAMBÉM o cabeçalho da rota (`module-heading`,
 *       `dossier-heading`, `competence-heading`) — o papel sai sem título, sem subtítulo e sem
 *       kicker, o que num relatório fiscal é perda de identificação, não de enfeite;
 *   (c) com o tema escuro ativo, os tokens do preview (`--paper`, `--ink`, `--line`…) continuam
 *       escuros: o `globals.css` neutraliza os tokens CANÔNICOS, não os do preview, e a página sai
 *       com fundo navy.
 *
 * As regras abaixo corrigem os três. O bridge é carregado DEPOIS do `globals.css` (o layout do grupo
 * injeta os `<link>`), então os `!important` daqui vencem por ordem, e os seletores de elemento +
 * classe ainda têm especificidade maior que o `header` nu do canônico. */
@media print {
  /* (a) o cromo vira uma coluna só — sem a trilha de 248px da sidebar. */
  .workspace-shell {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
  }
  .workspace-main {
    overflow: visible;
    padding: 0;
    background: none;
  }
  .workspace-content {
    width: 100%;
  }

  /* Moldura do cromo não vai ao papel (a trilha e as linhas decorativas incluídas). */
  .workspace-sidebar,
  .workspace-topbar,
  .workspace-footer,
  .workspace-grid-lines,
  .workspace-breadcrumb {
    display: none !important;
  }

  /* (b) os cabeçalhos DE ROTA voltam — são identificação do documento impresso. A `workspace-topbar`
     continua escondida acima; estas três classes são as usadas pelas rotas do grupo. */
  header.module-heading,
  header.dossier-heading,
  header.competence-heading {
    display: flex !important;
  }

  /* (c) tokens do preview em versão PAPEL quando a tela estava no escuro — mesmos valores do tema
     claro de alto contraste da própria folha aprovada (`html[data-contrast="high"]`), com `--ink` no
     navy institucional. O segundo seletor existe porque a folha declara os tokens escuros DE NOVO em
     `html[data-theme="dark"][data-contrast="high"]`, com especificidade maior. */
  html[data-theme="dark"],
  html[data-theme="dark"][data-contrast="high"] {
    color-scheme: light;
    --paper: #fff;
    --paper-deep: #eef1f2;
    --ink: #0d1b2a;
    --ink-soft: #243746;
    --muted: #3c4f5d;
    --line: #8797a2;
  }
}

/* ── H14 · sidebar: ritmo vertical dos blocos sem cabeçalho (veredito Felipe 04/08) ───────────
 *
 * A folha dá 17px entre TODOS os blocos da navegação e 4px entre itens; blocos SEM cabeçalho
 * (Consultas NCM/NBS; Documentos e apuração + Relatórios; Agenda progressiva) flutuavam com o
 * mesmo respiro dos blocos titulados — lidos como itens despadronizados. Veredito do Felipe
 * (2ª rodada): ritmo de ITEM — o bloco solto continua o fluxo do grupo acima a 4px
 * (17px do gap − 13px = 4px, o mesmo passo entre itens de um grupo). */
.workspace-navigation > .workspace-nav-group:not(:first-child):not(:has(> span)) {
  margin-top: -13px;
}

/* ── UX FINAL V1 · rodapé do SiteFooter (home V2, /calculadora, /login) ─────────────────────────
 *
 * 4 colunas — marca · produto · conta · legal. Cores SÓ por token da folha (`--navy-950`, `--white`,
 * `--yellow`): o texto secundário é o branco do token a 72% sobre o navy (≈9:1, AA), no lugar dos hex
 * crus que as folhas aprovadas aplicavam a `.footer-*`. Piso de 12px (o
 * legal estava em 10px). Seletores em `footer.site-footer.site-footer` (dobrado de propósito) para
 * vencer, sem `!important`, as regras de rodapé da `f1-design.css` (`html[data-theme] … footer`).
 * Mobile: 2 colunas (marca ocupa a linha) e links com 44px de altura de toque. */
html body footer.site-footer.site-footer {
  padding: 56px 0 28px;
  background: var(--navy-950);
  color: var(--white);
}
html body footer.site-footer.site-footer.site-footer--compact {
  padding: 28px 0;
}
footer.site-footer .sf-grid {
  display: grid;
  grid-template-columns: 1.5fr repeat(3, minmax(0, 1fr));
  gap: 32px clamp(24px, 4vw, 64px);
  align-items: start;
  padding-bottom: 40px;
}
footer.site-footer .sf-brand .brand-name {
  color: var(--white);
}
footer.site-footer .sf-col {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}
html body footer.site-footer.site-footer .sf-heading {
  display: block;
  margin-bottom: 8px;
  color: var(--white);
  font-size: var(--fs-caption);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
html body footer.site-footer.site-footer a.sf-link {
  display: flex;
  align-items: center;
  min-height: 32px;
  color: color-mix(in srgb, var(--white) 72%, transparent);
  font-size: 13px;
  text-decoration: none;
}
html body footer.site-footer.site-footer a.sf-link:hover,
html body footer.site-footer.site-footer a.sf-link:focus-visible {
  color: var(--white);
  text-decoration: underline;
}
html body footer.site-footer.site-footer a.sf-link:focus-visible {
  outline: 2px solid var(--yellow);
  outline-offset: 2px;
}
html body footer.site-footer.site-footer p.sf-text {
  margin: 0;
  color: color-mix(in srgb, var(--white) 72%, transparent);
  font-size: 13px;
  line-height: 1.55;
}
footer.site-footer .sf-brand p.sf-text {
  max-width: 420px;
  margin-top: 18px;
}
footer.site-footer .sf-legal {
  display: grid;
  grid-template-columns: 1.2fr 1fr auto;
  gap: 8px 28px;
  padding-top: 24px;
  border-top: 1px solid color-mix(in srgb, var(--white) 11%, transparent);
}
footer.site-footer.site-footer--compact .sf-legal {
  padding-top: 0;
  border-top: 0;
}
html body footer.site-footer.site-footer .sf-legal p.sf-text {
  font-size: var(--fs-caption);
}
@media (max-width: 860px) {
  footer.site-footer .sf-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 28px 24px;
  }
  footer.site-footer .sf-brand {
    grid-column: 1 / -1;
  }
  html body footer.site-footer.site-footer a.sf-link {
    min-height: 44px;
  }
  footer.site-footer .sf-legal {
    grid-template-columns: 1fr;
  }
}

/* ── G10 · fundação BeeDesign (A1) ───────────────────────────────────────────────────────────
 *
 * Tokens (`--fs-*`, `--control-h*`, `--radius-*`, `--space-*`) vivem em `app/globals.css` :root.
 * Este bloco liga o cromo V2 a eles: (1) família — a folha compilada declara `Inter` literal, que
 * o `next/font` NÃO registra com esse nome (vira família hasheada) e cai em Segoe UI; apontar
 * `--font-sans` para `--font-inter` faz o corpo renderizar de fato em Inter. (2) título de página
 * do workspace em Oxanium 700 no token. (3) pesos 640/660 da folha (renderizam 700) normalizados.
 * (4) altura de controle única. `.site-shell` (home pública) mantém o `--font-sans` próprio acima. */
:root {
  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;
}

/* Título de página do workspace: um tamanho, um peso, sem o letter-spacing de -2,3px do mockup. */
.workspace-intro h1,
.workspace-intro.workspace-intro-compact h1,
.module-heading h1,
.companies-heading h1 {
  font-family: var(--font-oxanium), ui-sans-serif, system-ui, sans-serif;
  font-size: var(--fs-page-title);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.01em;
}

/* Pesos: o piso dos controles/rótulos/células é 600; 640/660 da folha compilada viram 600/700. */
.button,
.button-compact,
.workspace-content th,
.workspace-content label,
.workspace-content legend,
.dossier-tabs a,
.dossier-tabs button,
.process-tabs a strong,
.agenda-view-tabs button,
.query-domain-tabs button {
  font-weight: 600;
}
.workspace-intro h2,
.module-card-heading h2,
.workspace-section-heading h2 {
  font-weight: 600;
}

/* Altura de controle: --control-h (44px) em botão e campo. */
.button,
.button.login-submit,
.form-field input,
.companies-toolbar input,
.competence-toolbar input,
.import-card input,
.import-card select,
.query-form-grid input,
.query-form-grid select,
.service-context input,
.batch-upload-controls input,
.batch-upload-controls select,
.batch-mapping-grid select,
.calendar-filter-card select,
.calendar-filter-card input,
.destination-filter select,
.report-builder-fields select {
  min-height: var(--control-h);
}

/* Botões compactos (barras de ação de tabela/card): 44px no toque, 36px com ponteiro fino. */
.button-compact,
.module-heading-actions .button,
.dossier-action-row .button,
.import-actions .button,
.batch-step .button,
.report-builder-fields .button,
.report-card-grid .button,
.query-form-grid .button,
.agenda-task-actions .button,
.legal-safety-note .button,
.calendar-filter-card > button,
.companies-filters button,
.refinement-mode-tabs button {
  min-height: var(--control-h);
}
@media (pointer: fine) {
  .button-compact,
  .module-heading-actions .button,
  .dossier-action-row .button,
  .import-actions .button,
  .batch-step .button,
  .report-builder-fields .button,
  .report-card-grid .button,
  .query-form-grid .button,
  .agenda-task-actions .button,
  .legal-safety-note .button,
  .calendar-filter-card > button,
  .companies-filters button,
  .refinement-mode-tabs button {
    min-height: var(--control-h-sm);
  }
}

/* ── G10 · botões V2 nos tokens BeeDesign (A2) ───────────────────────────────────────────────
 * Mesmo contrato do `.btn` de `app/globals.css`: altura `--control-h`, `--fs-button`/600, raio
 * `--radius-control`, anel de foco `--ring-focus` (cor `--focus-ring-color`, ≥3:1 nos 2 temas),
 * disabled/loading, sem transição em `prefers-reduced-motion`. Cor sai de token (âmbar da marca no
 * primário, contorno `--border-2` no secundário, `.button-ghost` novo). Gap/padding da folha compilada
 * ficam (a home aprovada usa as setas `span[aria-hidden]`). */
.button,
.button-compact {
  font-size: var(--fs-button);
  font-weight: 600;
  border-radius: var(--radius-control);
}
.button-primary {
  background: var(--brand);
  border-color: var(--brand);
  color: var(--action-contrast);
}
.button-primary:hover {
  background: var(--brand-hover);
  border-color: var(--brand-hover);
}
.button-secondary,
html[data-theme="dark"] .button-secondary {
  background: transparent;
  border-color: var(--border-2);
  color: var(--text);
}
.button-secondary:hover,
html[data-theme="dark"] .button-secondary:hover {
  background: transparent;
  border-color: var(--brand);
  color: var(--brand-text);
}
.button-ghost {
  background: transparent;
  border-color: transparent;
  color: var(--text-2);
}
.button-ghost:hover {
  background: var(--surface-3);
  color: var(--text);
}
.button:focus-visible,
.button-compact:focus-visible {
  outline: none;
  box-shadow: var(--ring-focus);
}
.button:disabled,
.button[aria-disabled="true"] {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none;
}
.button[aria-busy="true"] {
  cursor: progress;
  pointer-events: none;
}
.button[aria-busy="true"]::after {
  content: "";
  flex: none;
  width: 1em;
  height: 1em;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: btn-spin 0.7s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
  .button,
  .button-compact {
    transition: none;
  }
  .button:hover {
    transform: none;
  }
  .button[aria-busy="true"]::after {
    animation: none;
  }
}

/* ── G10 · campos V2 nos tokens BeeDesign (A2) ───────────────────────────────────────────────
 * Mesmo contrato do `.field-input`: `--fs-control` (15px), `--radius-control`, borda `--border-2`,
 * foco com `--ring-focus`, `[aria-invalid="true"]` em `--error`, disabled. Seletores = os mesmos
 * do bloco de altura de controle acima (+ textarea/select dos formulários V2). */
.form-field input,
.form-field select,
.form-field textarea,
.companies-toolbar input,
.competence-toolbar input,
.import-card input,
.import-card select,
.query-form-grid input,
.query-form-grid select,
.service-context input,
.batch-upload-controls input,
.batch-upload-controls select,
.batch-mapping-grid select,
.calendar-filter-card select,
.calendar-filter-card input,
.destination-filter select,
.report-builder-fields select {
  font-size: var(--fs-control);
  border-radius: var(--radius-control);
}
.form-field input:focus-visible,
.form-field select:focus-visible,
.form-field textarea:focus-visible,
.companies-toolbar input:focus-visible,
.competence-toolbar input:focus-visible,
.import-card input:focus-visible,
.import-card select:focus-visible,
.query-form-grid input:focus-visible,
.query-form-grid select:focus-visible,
.service-context input:focus-visible,
.batch-upload-controls input:focus-visible,
.batch-upload-controls select:focus-visible,
.batch-mapping-grid select:focus-visible,
.calendar-filter-card select:focus-visible,
.calendar-filter-card input:focus-visible,
.destination-filter select:focus-visible,
.report-builder-fields select:focus-visible {
  outline: none;
  border-color: var(--brand);
  box-shadow: var(--ring-focus);
}
.form-field input[aria-invalid="true"],
.form-field select[aria-invalid="true"],
.form-field textarea[aria-invalid="true"] {
  border-color: var(--error);
}
.form-field input:disabled,
.form-field select:disabled,
.form-field textarea:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}
.form-field label {
  font-size: var(--fs-label);
}

/* ── D1 · th das tabelas V2 compiladas no piso 13px (--fs-th) ─────────────────────────────────
 * A folha compilada (`ui-v2-preview-compiled.css`/`ui-v2-home.css`, byte-intactas por guarda) declara
 * `font-size` de th em 9px (`.companies-table`) e 5,6px (`.admin-data-table`): abaixo do piso de 13px.
 * O override mora aqui, no bridge, e aponta para o token (zero literal). */
.companies-table th,
.admin-data-table th {
  font-size: var(--fs-th);
}

/* ── E3 · M4 (decisão do Felipe 12/10) — topo do Monitor: KPIs à esquerda + mini-mês de prazos à direita ─
 * `.monitor-topo` envolve `.manager-kpis` e o card `.deadlines-panel.deadlines-mini`. Sem o card
 * (`gruposPrazo` indisponível) não há `--com-prazos` e os KPIs ocupam a largura, como antes. ≥1024: 2
 * colunas; abaixo disso empilha (≤768 inclusive). Só tokens BeeDesign (piso 13px, sem hex cru). */
.monitor-topo {
  display: grid;
  gap: 16px;
}
@media (min-width: 1024px) {
  /* M3 (decisão do Felipe 12/10): KPIs MAIS ESTREITOS (5fr) e o card do calendário com mais largura (6fr),
     para a grade do mês e as informações dos vencimentos caberem LADO A LADO dentro do card. */
  .monitor-topo.monitor-topo--com-prazos {
    grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
    align-items: stretch;
  }
  /* 5 KPIs em cartões individuais na coluna esquerda (cada um com a sua borda, sem a "régua" de 1px que
     deixaria uma célula vazia aparente). C4 (decisão do Felipe 12/10): grade REGULAR de 6 colunas em 2 linhas —
     Clientes · Faturamento anual · Carga mensal (span 2 cada) / Cobertura do mês · Atenção (span 3 cada); as
     duas linhas têm a MESMA altura (`repeat(2, 1fr)`) e a grade preenche a altura do card do calendário
     (`align-content: stretch`), sem sobra embaixo. Valores em R$ não truncam (quebra permitida). */
  .monitor-topo--com-prazos > .manager-kpis,
  .monitor-topo--com-prazos > .manager-kpis:has(> article:nth-child(5)) {
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: 12px;
    overflow: visible;
    border: 0;
    background: transparent;
    box-shadow: none;
    grid-template-rows: repeat(2, 1fr);
    align-content: stretch;
  }
  .monitor-topo--com-prazos > .manager-kpis > article {
    grid-column: span 3;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
  }
  .monitor-topo--com-prazos > .manager-kpis > article:nth-child(-n + 3) {
    grid-column: span 2;
  }
}
.deadlines-mini {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-content: start;
  gap: 0;
}
.deadlines-mini .deadlines-heading {
  padding: 14px 18px 8px;
}
.deadlines-mini .mini-mes {
  display: grid;
  gap: 6px;
  padding: 4px 18px 10px;
}
.deadlines-mini .mini-mes-rotulo {
  margin: 0;
  color: var(--text-2);
  font-size: var(--fs-caption);
  font-weight: 700;
}
/* Só a PRIMEIRA letra sobe ("Outubro de 2026"): `text-transform: capitalize` virava "Outubro De 2026". */
.deadlines-mini .mini-mes-rotulo::first-letter {
  text-transform: uppercase;
}
.deadlines-mini .mini-mes-semana,
.deadlines-mini .mini-mes-grade {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 4px;
  margin: 0;
  padding: 0;
  list-style: none;
  text-align: center;
}
.deadlines-mini .mini-mes-semana li {
  color: var(--text-3);
  font-size: var(--fs-caption);
  font-weight: 700;
}
.deadlines-mini .mini-mes-grade li {
  min-height: 28px;
  display: grid;
  place-items: center;
  border-radius: var(--radius-control);
  color: var(--text-2);
  font-size: var(--fs-caption);
}
.deadlines-mini .mini-mes-grade li.is-vencimento {
  border: 1px solid var(--brand-text);
  color: var(--brand-text);
  font-weight: 700;
}
.deadlines-mini .mini-mes-grade li.is-proximo {
  background: var(--brand);
  border: 1px solid var(--brand);
  color: var(--action-contrast);
  font-weight: 700;
}
.deadlines-mini .mini-mes-prazos {
  display: grid;
  border-top: 1px solid var(--border);
}
.deadlines-mini .deadline-item {
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 4px 12px;
  padding: 10px 18px;
  border-left: 0;
}
.deadlines-mini .deadline-item + .deadline-item {
  border-top: 1px solid var(--border);
}
.deadlines-mini .deadline-item > div span {
  display: block;
  overflow: hidden;
  font-size: 14px;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.deadlines-mini .deadline-item--segundo > div span {
  font-size: var(--fs-caption);
  font-weight: 400;
}
.deadlines-mini .deadline-item > .deadline-item-destinos {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 4px 12px;
}
.deadlines-mini .deadline-item > .deadline-item-destinos a {
  font-size: var(--fs-caption);
}
@media (max-width: 768px) {
  .deadlines-mini .deadline-item {
    grid-template-columns: minmax(0, 1fr);
  }
  .deadlines-mini .deadline-item > .deadline-item-destinos {
    grid-column: 1;
    justify-content: flex-start;
  }
}

/* ── M3 · Monitor gerencial: KPIs menores com fonte maior + calendário com grade e vencimentos lado a lado ─
 * (decisão do Felipe 12/10). Tudo escopado em `.portfolio-view` (só a rota /carteira o emite) ou em
 * `.monitor-topo--com-prazos`; nenhuma regra global de `.manager-kpis`/`.deadlines-mini` de outra tela é
 * tocada. Tokens BeeDesign (`--fs-*`); piso de 13px mantido. Valor em R$ NUNCA trunca: sem `ellipsis`,
 * quebra de linha permitida (o `title` do valor segue no componente). `container-type` no cartão deixa a
 * fonte do valor crescer com a largura do próprio cartão (`cqi`), do mínimo `--fs-num-lg` (24px, acima
 * dos 22px anteriores) até 30px. */
.portfolio-view .manager-kpis article {
  min-height: 0;
  align-content: center;
  gap: 2px;
  padding: 10px 12px;
  container-type: inline-size;
  /* C4: dados CENTRALIZADOS no cartão — rótulo, valor e legenda (com o selo de fonte) no eixo horizontal;
     o bloco todo no centro vertical (`align-content: center` acima). */
  justify-items: center;
  text-align: center;
}
.portfolio-view .manager-kpis span {
  font-size: var(--fs-body);
  font-weight: 600;
  line-height: 1.25;
}
.portfolio-view .manager-kpis strong {
  font-size: clamp(var(--fs-num-lg), 13cqi, 30px);
  line-height: 1.1;
  overflow: visible;
  text-overflow: clip;
  white-space: normal;
  overflow-wrap: break-word;
}
.portfolio-view .manager-kpis small {
  font-size: var(--fs-body-2);
  line-height: 1.3;
}
/* C4: abaixo de 1024 são 2 colunas e o 5º KPI (Atenção) ocupa a linha inteira. O `:has` iguala a
   especificidade da regra de 5 colunas do bridge (≥981), que de outro modo venceria entre 981 e 1023. */
@media (max-width: 1023px) {
  .portfolio-view .manager-kpis:has(> article:nth-child(5)) {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .portfolio-view .manager-kpis > article:nth-child(5):last-child {
    grid-column: 1 / -1;
  }
}
/* Celular estreito: 1 coluna, para o valor em R$ caber inteiro (sem quebrar no meio do número). */
@media (max-width: 560px) {
  .portfolio-view .manager-kpis:has(> article:nth-child(5)) {
    grid-template-columns: minmax(0, 1fr);
  }
}
@media (min-width: 1024px) {
  /* Card do calendário: a grade do mês à ESQUERDA e as informações dos vencimentos à lateral DIREITA,
     lado a lado; o cabeçalho do card ocupa as duas colunas. Abaixo de 1024 segue empilhado (grade em
     cima, informações embaixo — regra base `.deadlines-mini`). */
  .monitor-topo--com-prazos > .deadlines-mini {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-content: stretch;
  }
  .monitor-topo--com-prazos > .deadlines-mini > .deadlines-heading,
  .monitor-topo--com-prazos > .deadlines-mini > .deadline-item {
    grid-column: 1 / -1;
  }
  .monitor-topo--com-prazos > .deadlines-mini > .mini-mes {
    grid-column: 1;
    align-content: start;
    padding-bottom: 14px;
  }
  .monitor-topo--com-prazos > .deadlines-mini > .mini-mes-prazos {
    grid-column: 2;
    align-content: start;
    border-top: 0;
    border-left: 1px solid var(--border);
  }
  /* Lateral estreita: o item empilha (texto em cima, destinos embaixo) e o título do prazo quebra em
     linhas em vez de reticências — nada do vencimento fica escondido. */
  .monitor-topo--com-prazos > .deadlines-mini .deadline-item {
    grid-template-columns: minmax(0, 1fr);
  }
  .monitor-topo--com-prazos > .deadlines-mini .deadline-item > div span {
    overflow: visible;
    text-overflow: clip;
    white-space: normal;
  }
  .monitor-topo--com-prazos > .deadlines-mini .deadline-item > .deadline-item-destinos {
    grid-column: 1;
    justify-content: flex-start;
  }
}

/* M3 · h2 "Carteira" logo acima da lista de empresas (cromo V2): token de título de seção. */
.portfolio-view > .carteira-lista-titulo {
  margin: 0;
  color: var(--text);
  font-family: var(--font-oxanium), ui-sans-serif, system-ui, sans-serif;
  font-size: var(--fs-section-title);
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: -0.01em;
}

/* ── M3b · Calendário fiscal: título único + grade do mês com BORDA própria (decisão do Felipe 12/10) ─────
 * Escopo `.monitor-topo--com-prazos > .deadlines-mini` (card do Monitor gerencial; o `DeadlineStrip` legado não usa estas classes).
 * Só tokens existentes. Células quadradas (aspect-ratio) e uniformes, números a 13px (`--fs-caption`);
 * hoje = anel `--neon` (também por cima de vencimento/próximo, via `aria-current`), vencimento e próximo
 * seguem as regras do bloco anterior. A grade nunca excede o card (`minmax(0, 1fr)`): sem overflow a 375. */
.monitor-topo--com-prazos > .deadlines-mini .deadlines-heading h2 {
  font-size: 16px;
  font-weight: 600;
}
.monitor-topo--com-prazos > .deadlines-mini .mini-mes-quadro {
  display: grid;
  gap: 6px;
  min-width: 0;
  padding: 10px;
  border: 1px solid var(--border-2);
  border-radius: var(--radius-md);
}
.monitor-topo--com-prazos > .deadlines-mini .mini-mes-quadro .mini-mes-rotulo {
  text-align: center;
  color: var(--text);
  font-size: var(--fs-body-2);
}
.monitor-topo--com-prazos > .deadlines-mini .mini-mes-quadro .mini-mes-semana,
.monitor-topo--com-prazos > .deadlines-mini .mini-mes-quadro .mini-mes-grade {
  gap: 4px;
}
.monitor-topo--com-prazos > .deadlines-mini .mini-mes-quadro .mini-mes-semana li {
  line-height: 1.2;
}
.monitor-topo--com-prazos > .deadlines-mini .mini-mes-quadro .mini-mes-grade li {
  min-height: 0;
  aspect-ratio: 1 / 1;
  border: 1px solid transparent;
  background: var(--surface-2);
  font-size: var(--fs-caption);
  line-height: 1;
}
.monitor-topo--com-prazos > .deadlines-mini .mini-mes-quadro .mini-mes-grade li:empty {
  background: none;
}
.monitor-topo--com-prazos > .deadlines-mini .mini-mes-quadro .mini-mes-grade li.is-vencimento {
  border-color: var(--brand-text);
}
.monitor-topo--com-prazos > .deadlines-mini .mini-mes-quadro .mini-mes-grade li.is-proximo {
  background: var(--brand);
  border-color: var(--brand);
}
.monitor-topo--com-prazos > .deadlines-mini .mini-mes-quadro .mini-mes-grade li[aria-current="date"] {
  box-shadow: 0 0 0 2px var(--neon);
  font-weight: 700;
}

/* M3b · a seta do link fica colada à última palavra ("Ver calendário →", "Ver clientes ↓"): sem quebra
 * entre a palavra e a seta, nem no estado vazio (`.deadline-item > a`). */
.monitor-topo--com-prazos > .deadlines-mini .deadline-item-destinos a,
.monitor-topo--com-prazos > .deadlines-mini .deadline-item > a {
  white-space: nowrap;
}

/* ── F2 · piso de 13px no cromo V2 (achado ALTO do gate visual V1) ─────────────────────────────
 *
 * A folha compilada traz texto INFORMATIVO abaixo de 13px (nav 12px, subtítulos 11–12px, trilha 10px…).
 * Cada seletor abaixo é o MESMO da regra compilada (mesma especificidade) e vem depois dela, então
 * vence pela ordem — sem `!important`. Valor único: `--fs-hint` (13px).
 *
 * Fora desta lista, por decisão:
 *  - selo/badge de ESTADO (`.state-label`, `.count-badge`, `.calculation-status`, `.regime-verdict-badge`,
 *    `.legal-gate-badge`): já sobem para `--fs-badge` (11px, único papel autorizado) no bloco de selos;
 *  - decorativo `aria-hidden` mantido: ordinais `.workspace-nav-group a i` (`<i aria-hidden>`),
 *    `.accessibility-icon`, `.copilot-symbol`, `.reader-symbol`; `.theme-toggle` só tem ícone (SVG);
 *  - Início (`.workspace-tool strong`, `.portfolio-metrics dt/span`, `.next-action li strong`,
 *    `.workspace-section-heading > a`) já cobertos pelo bloco I1 logo abaixo (escopo `.inicio-v2`). */

/* Sidebar, trilha, rodapé da sidebar, menu mobile e Acessibilidade (cabeçalho). */
.workspace-nav-group a strong,
.workspace-sidebar-footer a,
.workspace-breadcrumb,
.accessibility-menu > summary,
.accessibility-heading a,
.text-size-controls,
.accessibility-toggle,
.accessibility-reset {
  font-size: var(--fs-hint);
}
@media (max-width: 900px) {
  .workspace-mobile-menu > summary {
    font-size: var(--fs-hint);
  }
}

/* Subtítulo (`<p>`) do cabeçalho das páginas: módulos, Dossiê, Competência, Empresas, Início. */
.module-heading > div:first-child > p:last-child,
.dossier-heading > div:first-child > p:last-child,
.competence-heading > div:first-child > p:last-child,
.companies-heading > div:first-child > p:last-child,
.workspace-intro-compact > div:first-child > p:last-child {
  font-size: var(--fs-hint);
}
@media (max-width: 480px) {
  .workspace-intro > div:first-child > p:last-child {
    font-size: var(--fs-hint);
  }
}

/* Demais textos informativos das superfícies V2 (workspace, Calculadora, Login, Home). */
.deadline-item > a,
.deadline-item > div span,
.next-action > p,
.service-context summary,
.eyebrow,
.footer-legal p,
.login-status,
.login-status:not(:empty),
.auth-signup,
.legal-review-note {
  font-size: var(--fs-hint);
}

/* ── S2 · Simuladores (`/simulador/operacao`, `/servico`, `/nfe`): tamanhos e alinhamento (decisão do Felipe 12/10) ──
 *
 * Tudo escopado por `.simulation-form-panel` (SÓ o `GradeWizardV2` dos 3 wizards emite) e `.simulacao-v2-stack`
 * (SÓ as 3 páginas). A Calculadora usa `.calculator-form-card`/`bf-form` e não é tocada. Só tokens existentes.
 *
 * C-01 · o formulário do wizard passa a medir o CONTAINER (`bf-wizard`), não a janela. Com resultado, a grade
 * `.simulation-workspace-grid` aperta o painel para ~330–550px e as utilitárias `sm:`/`lg:` (que medem a JANELA)
 * ainda pedem 2–3 colunas. As classes travadas por `wizards.c2.test.tsx` NÃO mudam: o CSS só reduz colunas, sempre
 * para BAIXO. `grid-column: auto` vai junto (um `col-span` remanescente fabricaria colunas implícitas).
 * Fieldset (seletor com legenda) ocupa a linha inteira no estado de 2 colunas, como no `sm:col-span-2` original. */
.simulation-form-panel {
  container-type: inline-size;
  container-name: bf-wizard;
}
@container bf-wizard (max-width: 559px) {
  .simulation-form-panel .grid[class*="grid-cols-"] {
    grid-template-columns: minmax(0, 1fr);
  }
  .simulation-form-panel .grid[class*="grid-cols-"] > * {
    grid-column: auto;
  }
  /* C-02: com 1 coluna não há vizinho a alinhar — o preenchimento de topo do checkbox de crédito some. */
  .simulation-form-panel [data-bf-rotulo-grade] {
    min-height: 0;
    padding-top: 0;
  }
}
@container bf-wizard (min-width: 560px) and (max-width: 899px) {
  .simulation-form-panel .grid[class*="lg:grid-cols-3"] {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .simulation-form-panel .grid[class*="lg:grid-cols-3"] > * {
    grid-column: auto;
  }
  .simulation-form-panel .grid[class*="lg:grid-cols-3"] > [class*="sm:col-span-2"],
  .simulation-form-panel .grid[class*="lg:grid-cols-3"] > fieldset {
    grid-column: 1 / -1;
  }
}
/* C-02: a reserva de rótulo de 3 colunas (legenda/rótulo de segmentado) só existe com 3 colunas (≥900px). */
@container bf-wizard (max-width: 899px) {
  .simulation-form-panel [data-bf-rotulo-grade="3"] {
    min-height: 0;
  }
}
/* A/B-1 (decisão do Felipe 12/10): seletor com legenda em UMA linha de 44px ao lado de UF/Ano/Documento. Como a
 * legenda precisa de ~380px, a linha com `fieldset` troca as colunas iguais por curta | flexível | larga (CSS
 * puro; as classes `lg:grid-cols-3` travadas pelo teste continuam no DOM). */
@container bf-wizard (min-width: 900px) {
  @media (min-width: 1024px) {
    .simulation-form-panel .grid[class*="lg:grid-cols-3"]:has(> fieldset) {
      grid-template-columns: minmax(0, 10rem) minmax(0, 1fr) minmax(0, 1.4fr);
    }
  }
}

/* C-04 · teto de largura do formulário (56rem = o `max-w-4xl` do cromo legado) quando ele ocupa a linha
 * inteira: NF sempre; venda/serviço antes do 1º resultado. Com resultado, a grade 0.68/1.32 manda. */
.invoice-simulator-layout[data-trilha] .simulation-form-panel,
.simulation-workspace-grid:not(:has(.simulation-results-column > *)) .simulation-form-panel {
  max-width: 56rem;
}

/* C-06 · o `.simulation-form-panel` cai para `padding: 15px` em ≤480px e a `BarraAcaoWizard` usa
 * `-mx-[var(--pad-card)]`: o token acompanha o padding real, a barra deixa de invadir 5px de cada lado. */
@media (max-width: 480px) {
  .simulation-form-panel {
    --pad-card: 15px;
  }
}

/* C-07 · os avisos (banner de projeção, aparte cruzado) trazem `mb-6` próprio e somam ao `gap` da pilha
 * (42px entre aviso e barra de passos contra 18px dos demais blocos): o espaçamento é só do `gap`. */
.simulacao-v2-stack > [role="note"] {
  margin-bottom: 0;
}

/* ── F4a · Calculadora: entrada consolidada em UM cabeçalho (decisão do Felipe, 12/10) ──────────────────
 * Posição no arquivo: logo ANTES do bloco C4 (e não no fim) de propósito — os testes `InicioV2.test.ts` (tudo
 * depois do marcador I1 precisa ser escopado por `.inicio-v2`) e `CardsEntrada.c4.test.tsx` (tudo entre C4 e I1
 * precisa mirar `.card-entrada`/leitor) travam as duas regiões vizinhas; este bloco não pertence a nenhuma.
 * Escopo: `.calculator-card-heading` dentro do `.calculator-form-card` da Calculadora V2 (SimuladorV2.tsx) e
 * o selo `.card-entrada-selo`, que só o `CardImportarDocumentos` emite. Estrutura: h2 "Dados do cenário" +
 * dica `t-hint`, na MESMA linha a ≥1024px (empilha abaixo disso). O respiro até os 3 cards é UM só: o
 * `margin-bottom` do cabeçalho (`--gap-card`); o contêiner `.calculator-document-reader` não tem margem
 * superior (a inferior, `--gap-section`, é da regra C4 abaixo). Só tokens; nenhuma regra global alterada. */
[data-skin="v2"] .calculator-form-card .calculator-card-heading {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: calc(var(--gap-card) / 4);
  margin-bottom: var(--gap-card);
}
[data-skin="v2"] .calculator-form-card .calculator-card-heading > p {
  margin: 0;
}
@media (min-width: 1024px) {
  [data-skin="v2"] .calculator-form-card .calculator-card-heading {
    flex-direction: row;
    align-items: baseline;
    justify-content: flex-start;
    gap: var(--gap-card);
  }
}
/* Selo "Extração determinística" no card Importar: discreto (texto `--text-2` ≥13px via `t-hint`, contorno
 * `--border-2`, fundo `--surface-2`), em pílula — sem sombra, sem preenchimento de card. Alinha à direita da
 * linha do título (`margin-inline-start: auto`) e quebra natural para a linha de baixo se não couber. */
.card.card-entrada .card-entrada-selo {
  margin-inline-start: auto;
  padding: 0 calc(var(--pad-card-compact) / 2);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-pill);
  background: var(--surface-2);
  color: var(--text-2);
  font-weight: 600;
  white-space: nowrap;
}

/* ── F4a-E · Calculadora: "Enquadramento no Simples Nacional" vira FAIXA em "Dados fiscais" (Felipe, 12/10) ──
 * O trilho direito (`.simulador-form-trilho` + `.simulador-painel-simples*`, decisão E3·C2) foi REVOGADO e
 * removido; suas regras saíram deste arquivo (grade 8/4 em container ≥1040px, `align-self: stretch`, painel
 * `flex: 1 1 auto`, conteúdo `position: sticky`). Esta faixa é o `section.simulador-faixa-simples` que o
 * `FormularioSimulacao` emite logo abaixo da linha Atividade | Regime atual | Tributação específica.
 * Pele: card plano — contorno `--border-2`, fundo `--surface-2`, preenchimento `--pad-card-compact`, raio
 * `--radius-card`; sem sombra e sem sticky. Layout horizontal decidido pela largura REAL do formulário
 * (container `bf-form`, mesma razão de P-162) a partir de 1024px: título e frase legal na MESMA linha, corpo em 2
 * colunas (Anexo | Enquadramento estimado); abaixo disso, tudo empilha. Só tokens. */
[data-skin="v2"] .simulador-faixa-simples {
  padding: var(--pad-card-compact);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-card);
  background: var(--surface-2);
}
[data-skin="v2"] .simulador-faixa-simples-topo {
  display: flex;
  flex-direction: column;
  gap: calc(var(--gap-card) / 4);
}
[data-skin="v2"] .simulador-faixa-simples-topo > h3,
[data-skin="v2"] .simulador-faixa-simples-topo > p {
  margin: 0;
}
[data-skin="v2"] .simulador-faixa-simples-rodape {
  display: flex;
  flex-wrap: wrap;
  column-gap: var(--gap-card);
  row-gap: calc(var(--gap-card) / 4);
}
[data-skin="v2"] .simulador-faixa-simples-rodape > p {
  margin: 0;
}
@container bf-form (min-width: 1024px) {
  [data-skin="v2"] .simulador-faixa-simples-topo {
    flex-direction: row;
    align-items: baseline;
    gap: var(--gap-card);
  }
  [data-skin="v2"] .simulador-faixa-simples-corpo {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: var(--gap-card);
    align-items: start;
  }
}

/* ── F4b · Calculadora: campo R$ com seletor Anual|Mensal na MESMA linha (Felipe, 12/10) ──────────────────────
 * Escopo: só `.simulador-moeda-anualizavel` (o `Field` de `CampoMoedaAnualizavel`, em `campos.tsx`) e a linha
 * `.simulador-moeda-linha` que ele emite — nenhuma regra global, nenhum seletor de tag solto. O card vira um
 * CONTAINER próprio (`bf-moeda`, inline-size) para a linha se arranjar pela largura REAL do card (a grade de
 * "Dados econômicos" muda de 3 para 2 e 1 colunas por outro container, `bf-form`): com folga, input R$ e seletor
 * dividem a linha (44px, tudo centralizado na vertical); abaixo de 18rem de conteúdo, o seletor quebra para baixo
 * do input, alinhado à esquerda, e o input ocupa a largura toda. Só tokens/medidas relativas. */
[data-skin="v2"] .simulador-moeda-anualizavel {
  container-type: inline-size;
  container-name: bf-moeda;
}
@container bf-moeda (max-width: 18rem) {
  [data-skin="v2"] .simulador-moeda-linha {
    flex-wrap: wrap;
    row-gap: calc(var(--gap-field-y) / 2);
  }
  [data-skin="v2"] .simulador-moeda-linha > .relative {
    flex-basis: 100%;
  }
}

/* ── C4 · Calculadora: os 3 cards de entrada (Importar | Coletar | Copiloto) viram cards de verdade ───────
 * (decisão do Felipe 12/10). Escopo: a classe `.card-entrada`, que SÓ os três cards da faixa "Preencher
 * automaticamente" emitem (`CardImportarDocumentos`, `CardColetaCliente`, `CopilotoIA`) — nenhuma outra
 * tela usa. Só tokens existentes: contorno `--border-2` (mais visível que o `--border` do `.card`), raio
 * `--radius-card`, elevação `--shadow-card` (claro: sombra navy suave; escuro: sombra + realce interno de
 * 1px), fundo `--surface` no claro e `--surface-2` no escuro (um degrau acima do contêiner). Mesma altura
 * vem do `h-full` na grade; a ação é o último filho do card (fica na base). Hover/foco: borda `--neon`.
 *
 * Profundidade: o contêiner imediato dos 3 cards (`section.calculator-document-reader`) deixa de ser card
 * (sem borda, fundo, sombra, raio nem preenchimento próprios) — vira agrupamento plano, tirando 1 nível de
 * card-em-card. F4a (12/10): esse contêiner já não tem `<header>` (sem "Leitor documental nativo", "Entrada
 * estruturada", "⇩" nem selo); o rótulo acessível é `aria-label="Preencher automaticamente"` e o cabeçalho
 * da área é um só (h2 "Dados do cenário" + dica, bloco "F4a" no fim deste arquivo). */
.card.card-entrada {
  border: 1px solid var(--border-2);
  border-radius: var(--radius-card);
  background: var(--surface);
  box-shadow: var(--shadow-card);
}
html[data-theme="dark"] .card.card-entrada {
  background: var(--surface-2);
}
.card.card-entrada:hover {
  border-color: var(--neon);
}
.card.card-entrada:focus-within {
  border-color: var(--neon);
  box-shadow: 0 0 0 1px var(--neon), var(--shadow-card);
}
/* Placeholder do Copiloto (decisão do Felipe 12/10: o exemplo "parecia texto preenchido"): orientação em tom
 * terciário MAIS CLARO que o texto digitado, nos 2 temas — `--text-3` misturado 80% com o fundo do campo
 * (`--surface-2`), por token. Contraste sobre o campo ≈ 4,4:1 (claro) e ≈ 6,8:1 (escuro), ambos ≥ 3:1, contra
 * ≈ 16:1 / ≈ 13:1 do texto digitado. `opacity: 1` anula o 0.82 do bloco legado do `.calculator-text-copilot`. */
.card.card-entrada textarea::placeholder {
  color: color-mix(in srgb, var(--text-3) 80%, var(--surface-2));
  opacity: 1;
}
[data-skin="v2"] .calculator-form-card .calculator-document-reader {
  /* Respiro entre a faixa dos 3 cards e a seção ② "Dados fiscais" que vem em seguida: o mesmo token de seção
   * que separa as demais seções do formulário (o ramo legado já recebe `--gap-section` do `space-y` do pai). */
  margin-bottom: var(--gap-section);
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
}

/* ── I1 · `/inicio` cabe na tela sem rolagem em desktop (decisão do Felipe, 12/10, opção A) ────
 *
 * Tudo escopado pelo modificador `.inicio-v2`, que SÓ o `InicioV2` emite (intro, faixa de atalhos,
 * grade inferior e os dois cartões). Nenhuma regra global das classes compartilhadas
 * (`.workspace-section`, `.workspace-section-heading`, `.workspace-kicker`, `.workspace-tool*`,
 * `.portfolio-metrics`, `.next-action`) é alterada: as outras telas do grupo seguem como estavam.
 * O prefixo `.workspace-content` sobe a especificidade acima das regras de tema escuro e dos
 * `@media` da folha compilada (que usam classe única) sem recorrer a `!important`.
 * Medidas só por tokens (`--gap-card`, `--pad-card-compact`, `--control-h`, `--fs-*`).
 * Faixa de atalhos: auto-fit com mínimo de 140px ⇒ 7 colunas em ≥1366 e quebra em 4/3/2 colunas nas
 * telas estreitas, sem overflow horizontal. */

/* Espaço entre os blocos do Início: o token de gap de cartão, em vez dos 18px do cromo. */
.workspace-content:has(> .inicio-v2) {
  gap: var(--gap-card);
}

/* 1 · Cabeçalho: só o h1, padding vertical mínimo (sem subtítulo nem hexágono). */
.workspace-content .workspace-intro.workspace-intro-compact.inicio-v2 {
  min-height: 0;
  padding: calc(var(--pad-card-compact) / 2) var(--pad-card-compact);
}

/* 2 · Atalhos: faixa única de tiles (ícone + nome), sem o cartão em volta. */
.workspace-content .inicio-v2.workspace-tools {
  padding: 0;
  border: 0;
  background: none;
  box-shadow: none;
}
.workspace-content .inicio-v2 .workspace-tool-grid {
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  margin-top: 0;
}
.workspace-content .inicio-v2 .workspace-tool {
  min-height: var(--control-h);
  grid-template-columns: 32px minmax(0, 1fr);
  gap: calc(var(--pad-card-compact) / 2);
  padding: calc(var(--pad-card-compact) / 2);
}
.workspace-content .inicio-v2 .workspace-tool > span {
  width: 32px;
  height: 32px;
}
.workspace-content .inicio-v2 .workspace-tool strong {
  font-size: var(--fs-caption);
  font-weight: 600;
  line-height: 1.25;
}

/* Cartões da grade inferior: padding compacto e cabeçalho de uma linha. */
.workspace-content .inicio-v2.portfolio-overview,
.workspace-content .inicio-v2.next-action {
  padding: var(--pad-card-compact);
}
.workspace-content .inicio-v2 .workspace-section-heading {
  flex-direction: row;
  flex-wrap: wrap;
  align-items: baseline;
  gap: calc(var(--pad-card-compact) / 4) var(--gap-card);
}
.workspace-content .inicio-v2 .workspace-section-heading h2 {
  font-size: var(--fs-card-title);
  line-height: 1.25;
}
.workspace-content .inicio-v2 .workspace-section-heading > a {
  font-size: var(--fs-caption);
}
.workspace-content .inicio-v2 .workspace-kicker {
  margin-bottom: calc(var(--pad-card-compact) / 4);
}

/* 3 · Grade inferior: carteira ≈1/3 e ações ≈2/3 a partir de 1280px; abaixo, uma coluna. */
.workspace-content .inicio-v2.workspace-dashboard-grid {
  grid-template-columns: minmax(0, 1fr);
  gap: var(--gap-card);
  align-items: stretch;
}
@media (min-width: 1280px) {
  .workspace-content .inicio-v2.workspace-dashboard-grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
  }
}

/* Resumo: 4 métricas em 2×2 compactas (valor + sublegenda preservados). */
.workspace-content .inicio-v2.portfolio-overview {
  display: flex;
  flex-direction: column;
}
.workspace-content .inicio-v2 .portfolio-metrics {
  flex: 1;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-auto-rows: 1fr;
  margin-top: calc(var(--pad-card-compact) / 2);
}
@media (min-width: 768px) and (max-width: 1279px) {
  .workspace-content .inicio-v2 .portfolio-metrics {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}
.workspace-content .inicio-v2 .portfolio-metrics > div {
  min-height: 0;
  gap: calc(var(--pad-card-compact) / 4);
  padding: calc(var(--pad-card-compact) * 0.75);
}
.workspace-content .inicio-v2 .portfolio-metrics dt,
.workspace-content .inicio-v2 .portfolio-metrics span {
  font-size: var(--fs-caption);
  line-height: 1.3;
}
.workspace-content .inicio-v2 .portfolio-metrics dd {
  overflow: hidden;
  font-size: var(--fs-card-title);
  font-weight: 700;
  line-height: 1.3;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 4 · Ações do dia: linha 1 = nº + título; linha 2 = "motivo · consequência"; CTA à direita (≥1024). */
.workspace-content .inicio-v2.next-action ol {
  margin-top: calc(var(--pad-card-compact) / 2);
}
.workspace-content .inicio-v2.next-action li {
  grid-template-columns: 25px minmax(0, 1fr);
  gap: calc(var(--pad-card-compact) * 0.75);
  padding: calc(var(--pad-card-compact) / 2) 0;
}
.workspace-content .inicio-v2.next-action li > div {
  grid-template-columns: minmax(0, 1fr);
  gap: calc(var(--pad-card-compact) / 4);
}
.workspace-content .inicio-v2.next-action li strong {
  font-size: var(--fs-body-2);
  font-weight: 600;
  line-height: 1.4;
}
.workspace-content .inicio-v2.next-action li small {
  font-size: var(--fs-caption);
  line-height: 1.45;
}
.workspace-content .inicio-v2.next-action li .button {
  margin-top: calc(var(--pad-card-compact) / 4);
  min-height: var(--control-h);
  white-space: nowrap;
}
@media (min-width: 1024px) {
  .workspace-content .inicio-v2.next-action li > div {
    grid-template-columns: minmax(0, 1fr) auto;
    column-gap: var(--gap-card);
    align-items: center;
  }
  .workspace-content .inicio-v2.next-action li strong,
  .workspace-content .inicio-v2.next-action li small {
    grid-column: 1;
  }
  .workspace-content .inicio-v2.next-action li .button {
    grid-column: 2;
    grid-row: 1 / span 2;
    margin-top: 0;
    justify-self: end;
  }
}
@media (min-width: 1024px) and (pointer: fine) {
  .workspace-content .inicio-v2.next-action li .button {
    min-height: var(--control-h-sm);
  }
}

/* ── I2 · `/inicio` preenche a altura da tela em desktop (decisão do Felipe, 13/10: "tudo estica até o fim da tela") ──
 *
 * Continua tudo escopado por `.inicio-v2` (todo seletor desta fatia o contém) e só vale de 1280px para cima;
 * abaixo disso (768, 375) NENHUMA regra da I2 se aplica. Crescimento = SÓ distribuição de sobra
 * (`flex-grow` sobre o que sobra do `min-height`): nenhuma altura fixa maior que a viewport, logo a I2 não
 * pode criar rolagem por si — o que cria rolagem é crescer o conteúdo NATURAL, e é por isso que a
 * descrição dos atalhos (a única coisa que aumenta o conteúdo natural) só aparece com altura de sobra.
 *
 * Orçamento vertical (altura disponível ao `.workspace-content` = viewport − topbar − 2 × padding do main):
 *  · topbar: `.workspace-topbar` tem `min-height: 64px` (ui-v2-home.css:4942, border-box, borda inclusa) e o
 *    conteúdo dela (chip 38px + 2 × 8px) cabe em 64 ⇒ 64px; a variável usa 65px (1px de folga: errar para
 *    cima só deixa 1px de vão no rodapé, errar para baixo criaria rolagem). Rodapé do shell removido (P-747).
 *  · padding do main: `clamp(20px, 2.2vw, 36px)` em cima e embaixo (ui-v2-home.css:5026) ⇒ 30px a 1366,
 *    32px a 1440, 36px a 1920.
 *  · disponível: 1366×768 ⇒ 768 − 65 − 60 = 643px · 1440×900 ⇒ 900 − 65 − 63 = 772px · 1920×1080 ⇒ 1080 − 65 − 72 = 943px.
 *  · limiar da descrição dos atalhos: `min-height: 840px`. Conta: conteúdo natural da I1 (≈ 506–600px, faixa
 *    estimada pela I1; 600 no pior caso a 1366) + o que a descrição acrescenta ao conteúdo natural (tile
 *    ≈ 120–135px contra ≈ 48px da I1 ⇒ ≈ +87px; métricas a 24px ⇒ até ≈ +50px se o valor quebrar) ⇒ ≈ 640–740px
 *    naturais ⇒ viewport ≥ 640..740 + 65 + 2 × ≈ 32 ⇒ ≈ 770..870px. 840px atende com folga a janela
 *    1440×900 de gate (innerHeight 843) e 1920×1080 (innerHeight ≈ 950), e deixa 1366×768 (innerHeight ≈ 650)
 *    na I1: sem descrição e sem rolagem. Estimativa por conta: a medição real no navegador é o gate desta fatia. */

/* Descrição do atalho: DESDE a I1 existe no DOM como `aria-describedby` do link, fora do nome acessível.
 * Fora da media abaixo ela é só para leitor de tela (mesma técnica visual do `.sr-only`) e o `div` envolvente
 * não gera caixa — o link segue sendo o item da grade, exatamente como na I1. */
.workspace-content .inicio-v2 .inicio-v2-atalho {
  display: contents;
}
.workspace-content .inicio-v2 .inicio-v2-atalho-desc {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ≥1280px: o contêiner do Início vira coluna flex com a altura da viewport menos topbar e padding do main;
 * a grade inferior recebe a sobra e os dois cartões esticam. */
@media (min-width: 1280px) {
  .workspace-content:has(> .inicio-v2) {
    --inicio-v2-topbar: 65px;
    display: flex;
    flex-direction: column;
    min-height: calc(100dvh - var(--inicio-v2-topbar) - 2 * clamp(20px, 2.2vw, 36px));
  }
  /* Grade inferior (Resumo + Ações) e, sem carteira, o cartão de ações sozinho: absorvem a sobra. */
  .workspace-content > .inicio-v2.workspace-dashboard-grid,
  .workspace-content > .inicio-v2.next-action {
    flex: 3 1 auto;
  }
  .workspace-content .inicio-v2.next-action {
    display: flex;
    flex-direction: column;
  }

  /* Resumo: as 4 métricas já ocupam a altura do cartão (`flex: 1` + linhas `1fr` da I1); aqui o valor
   * deixa de ser cortado — pode quebrar a linha, nunca vira reticências. */
  .workspace-content .inicio-v2 .portfolio-metrics dd {
    overflow: visible;
    text-overflow: clip;
    white-space: normal;
    overflow-wrap: break-word;
  }

  /* Ações: a lista distribui os itens na altura do cartão (CTA não estica); estado vazio centralizado. */
  .workspace-content .inicio-v2.next-action ol {
    flex: 1;
    display: grid;
    grid-auto-rows: minmax(auto, 1fr);
  }
  .workspace-content .inicio-v2.next-action li {
    align-items: center;
  }
  .workspace-content .inicio-v2.next-action > p {
    flex: 1;
    display: grid;
    align-content: center;
  }
}

/* ≥1280px COM altura: atalhos mais altos com a descrição visível (13px, até 2 linhas), métricas maiores e
 * os atalhos também recebem sobra (peso 1 contra 3 da grade inferior). Limiar justificado no cabeçalho. */
@media (min-width: 1280px) and (min-height: 840px) {
  .workspace-content > .inicio-v2.workspace-tools {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
  }
  /* Faixa de uma linha só (7 colunas iguais), qualquer que seja a largura ≥1280, e a linha estica. */
  .workspace-content .inicio-v2 .workspace-tool-grid {
    flex: 1;
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
  }
  .workspace-content .inicio-v2 .inicio-v2-atalho {
    position: relative;
    display: grid;
    min-width: 0;
  }
  /* Tile empilhado (ícone, nome); o espaço da descrição (2 linhas de `--fs-body-2` × 1.45) é reservado embaixo. */
  .workspace-content .inicio-v2 .inicio-v2-atalho .workspace-tool {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    justify-content: center;
    gap: calc(var(--pad-card-compact) / 2);
    padding: calc(var(--pad-card-compact) * 0.75);
    padding-bottom: calc(var(--pad-card-compact) * 0.75 + var(--fs-body-2) * 2.9);
  }
  .workspace-content .inicio-v2 .inicio-v2-atalho .workspace-tool strong {
    font-size: var(--fs-body);
  }
  /* Ícone do atalho maior (pedido do Felipe 13/10): caixa 56px, glifo 28px. Sem token de ícone no projeto. */
  .workspace-content .inicio-v2 .inicio-v2-atalho .workspace-tool > span {
    width: 56px;
    height: 56px;
  }
  .workspace-content .inicio-v2 .inicio-v2-atalho .workspace-tool > span svg {
    width: 28px;
    height: 28px;
  }
  .workspace-content .inicio-v2 .inicio-v2-atalho-desc {
    position: absolute;
    inset-inline: calc(var(--pad-card-compact) * 0.75);
    bottom: calc(var(--pad-card-compact) * 0.75);
    width: auto;
    height: auto;
    margin: 0;
    overflow: hidden;
    clip: auto;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    white-space: normal;
    color: var(--muted);
    font-size: var(--fs-body-2);
    line-height: 1.45;
    text-align: center;
    pointer-events: none;
  }

  /* Resumo (pedido do Felipe 13/10): rótulo, valor e legenda maiores para o conteúdo preencher o card.
   * "sem dado" (ausência) continua discreto, sem virar destaque; o selo de fonte (span aninhado) não muda. */
  .workspace-content .inicio-v2 .portfolio-metrics dt {
    font-size: var(--fs-card-title);
  }
  .workspace-content .inicio-v2 .portfolio-metrics dd {
    font-size: var(--fs-display);
    line-height: 1.2;
  }
  .workspace-content .inicio-v2 .portfolio-metrics .is-sem-dado dd {
    font-size: var(--fs-section-title);
    font-weight: 600;
  }
  .workspace-content .inicio-v2 .portfolio-metrics > div > span {
    font-size: var(--fs-body-2);
  }
}

/* Adendo da I2 (Felipe, 13/10): no Resumo da carteira o conteúdo de cada card de métrica (rótulo, valor,
 * legenda e selo de fonte) fica CENTRALIZADO, na horizontal e na vertical (o card agora estica). Vale onde
 * a grade 2×2 aparece: abaixo de 768px (uma coluna de 2×2) e a partir de 1280px; entre 768 e 1279 a grade é
 * 4×1 (I1) e não muda. O selo e a legenda seguem juntos na mesma linha quando couber. */
@media (max-width: 767px), (min-width: 1280px) {
  .workspace-content .inicio-v2 .portfolio-metrics > div {
    align-content: center;
    justify-items: center;
    text-align: center;
  }
  .workspace-content .inicio-v2 .portfolio-metrics > div > * {
    min-width: 0;
    max-width: 100%;
  }
  .workspace-content .inicio-v2 .portfolio-metrics > div > span {
    justify-content: center;
    flex-wrap: wrap;
  }
}
