/*
 * ft-chat-surface.css — a superfície do chat do assistente: tela cheia (Views/Ai/Index.cshtml) e modal (Views/Ai/Panel.cshtml,
 * a página do iframe). Plano docs/Features/support.md, passo B1 (decisão 2: uma superfície visual para os dois assistentes,
 * o chat IA e o Balcão).
 *
 * ORIGEM — até 2026-09-29 isto era o <style> de Views/Ai/_FtAiChatStyle.cshtml, extraído da Ai/Index.cshtml em
 * 2026-09-21 para a tela cheia e a modal pintarem igual (par de _FtAiChatPanel, _FtAiChatRail e _FtAiChatScript).
 * Mudou só de LUGAR: as mesmas regras, com os mesmos seletores e na mesma ordem; o "@@" que o Razor exigia voltou a ser
 * "@". É o ÚLTIMO arquivo de ~/wwwroot/css/fixtres-components (bundles.json), e as duas páginas renderizavam o <style>
 * logo depois desse bundle — então a posição na cascata é a mesma de antes. Efeito colateral aceito: as outras telas
 * que carregam o bundle também baixam este arquivo; nada aqui casa fora do chat (tudo é .ft-ai-*, e
 * ".ft-tree__row > .ft-mixbar" só existe no trace do chat — conferido em 2026-09-29).
 *
 * TOKENS --ft-chat-* — os valores de hoje do chat, declarados uma vez aqui e lidos pelas regras abaixo. O Balcão
 * (ft-assistant-desk.css) lê os que têm o MESMO valor nele, sempre com fallback literal (a Home não carrega este arquivo),
 * e mantém literal o que difere — anotado ao lado de cada token. No :root porque o data-theme mora no <html>: um token
 * que aponta para cor do tema resolve ali com o tema certo.
 */
:root {
    --ft-chat-log-gap: 10px;                                         /* chat e Balcão */
    --ft-chat-bubble-pad: 10px 14px;                                 /* chat e Balcão */
    --ft-chat-bubble-radius: 16px;                                   /* chat e Balcão */
    --ft-chat-bubble-tail: 6px;                                      /* o canto do lado de quem fala; chat e Balcão */
    --ft-chat-bubble-max: 80%;                                       /* só o chat; o Balcão limita o .ft-desk-msg a 90% */
    --ft-chat-bubble-bg: var(--ft-color-surface-2, #f5f5f5);         /* bolha do assistente; a do Balcão é #eef3ee */
    --ft-chat-bubble-user-bg: var(--ft-color-primary-soft, #eef2ff); /* a do Balcão é verde #008927, texto branco */
    --ft-chat-chip-radius: 999px;                                    /* pílula; chat (anexo) e Balcão (opção) */
    --ft-chat-chip-bg: var(--ft-bg-subtle, #f2f4f7);                 /* só o chip de anexo; o do Balcão não tem fundo */
    --ft-chat-chip-border: 1px solid var(--ft-border, #e4e7ec);      /* a do Balcão é 1.5px verde */
}

/* `flex: 1` + `min-height: 0` é o par que faz a rolagem acontecer AQUI e não no card. Sem o
   `min-height: 0`, um filho flex se recusa a encolher abaixo do conteúdo e o overflow vaza para fora. */
/* Respiro e balões do redesenho "palco e conversa" (2026-09-23, tests/assistant-3d/assistant-ui.css › .assistant-log/
   .assistant-msg): raio 16 com o canto do lado de quem fala mais fechado (6px), como rabinho de balão. */
.ft-ai-log { flex: 1 1 auto; min-height: 0; overflow-y: auto; display: flex; flex-direction: column;
             gap: var(--ft-chat-log-gap); padding: 18px 4px 12px 0; }
.ft-ai-msg { max-width: var(--ft-chat-bubble-max); padding: var(--ft-chat-bubble-pad); border-radius: var(--ft-chat-bubble-radius); }
.ft-ai-msg--user { align-self: flex-end; background: var(--ft-chat-bubble-user-bg);
                   border-bottom-right-radius: var(--ft-chat-bubble-tail); }
.ft-ai-msg--assistant { align-self: flex-start; background: var(--ft-chat-bubble-bg);
                        border-bottom-left-radius: var(--ft-chat-bubble-tail); }
/* Um turno pode trazer VÁRIOS artefatos (gráfico + tabela). Cada um tem rolagem horizontal própria;
   o teto de 420px vale só para o SVG, porque a tabela precisa da largura toda. */
.ft-ai-msg__artifact { margin-top: .5rem; max-width: 100%; overflow-x: auto; }
.ft-ai-msg__artifact svg { width: 100%; height: auto; max-width: 420px; }
.ft-ai-msg__artifact table { width: 100%; }
.ft-ai-msg__artifact--error { color: var(--ft-color-danger, #b42318); white-space: pre-wrap; }

/* Ações do artefato (Passo 11.10). Fora do overflow do artefato, senão a barra rolaria com a tabela. */
.ft-ai-artifact-actions { display: flex; flex-wrap: wrap; gap: .35rem; align-items: center;
                          margin-top: .4rem; }
.ft-ai-artifact-actions__status { font-size: .8rem; color: var(--ft-color-text-muted, #667085); }

/* Markdown do texto do modelo (MdLite). Espaçamento apertado de propósito: é bolha de conversa, não
   página — margem de documento faria cada resposta parecer três parágrafos soltos. */
.ft-ai-md__p + .ft-ai-md__p { margin-top: .5rem; }
.ft-ai-md__h { margin: .6rem 0 .3rem; font-size: .95rem; font-weight: 600; }
.ft-ai-md__p:first-child, .ft-ai-md__h:first-child { margin-top: 0; }
.ft-ai-md__list { margin: .35rem 0; padding-left: 1.25rem; }
.ft-ai-md__list li + li { margin-top: .15rem; }
.ft-ai-msg__text code { background: var(--ft-color-surface-3, #ececec); border-radius: .2rem;
                        padding: .05rem .25rem; font-size: .85em; }
.ft-ai-md__pre { background: var(--ft-color-surface-3, #ececec); border-radius: .3rem;
                 padding: .5rem .6rem; margin: .4rem 0; overflow-x: auto; }
.ft-ai-md__pre code { background: none; padding: 0; font-size: .85em; }
/* Rolagem no container, nunca no body (a bolha tem largura limitada). */
.ft-ai-md__tablewrap { margin: .4rem 0; overflow-x: auto; max-width: 100%; }
.ft-ai-md__table { width: 100%; border-collapse: collapse; font-size: .85rem; }
.ft-ai-md__table th, .ft-ai-md__table td { border: 1px solid var(--ft-color-border, #e4e7ec);
                                           padding: .25rem .45rem; text-align: left; }

/* Trace do turno: linha de tempo colapsável. O trilho é a borda esquerda do <ol>. */
/* Faixa do cabecalho: o botao e a barra de mistura lado a lado. A barra NAO pode ficar
   dentro do botao — ela carrega um cartao `<div>` de hover, e `<div>` dentro de `<button>` e
   conteudo invalido: era por isso que o hover do topo nao abria. Mesma razao da nota em `no()`. */
.ft-ai-trace__head { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.ft-ai-trace__toggle { background: none; border: 0; padding: .15rem 0; cursor: pointer; font: inherit;
                       font-size: .8rem; color: var(--ft-color-text-muted, #667085); display: flex;
                       align-items: center; gap: .35rem; }
.ft-ai-trace__toggle:hover { color: var(--ft-color-text, #101828); }
.ft-ai-trace__caret { transition: transform .15s ease; }
.ft-ai-trace--open .ft-ai-trace__caret { transform: rotate(90deg); }
.ft-ai-trace__body { display: none; margin: .4rem 0 0; }
.ft-ai-trace--open .ft-ai-trace__body { display: block; }

/* Barra de mistura da rodada: proporcao dos quatro contadores num relance. A barra E o
   componente `FtMixBar` (`Scripts/Components/ft-mixbar.js`) — trilho, segmentos, cartao de
   hover e posicionamento moram la; a identidade das cores mora no tema (`--ft-tok-*`). Aqui
   fica so o que e DESTA tela: o respiro a esquerda do texto que a barra acompanha.
   O detalhe mora no hover porque a tira e densa — quatro numeros por rodada, quatro rodadas,
   e a linha ficava longa demais para ser lida. */
.ft-ai-trace__head .ft-mixbar,
.ft-tree__row > .ft-mixbar { margin-left: 6px; }

/* Bola da rodada: o numero E o rotulo. "rodada 3" gastava seis vezes mais largura para
   dizer a mesma coisa numa lista onde a ordem ja e obvia. */
.ft-ai-round { display: inline-grid; place-items: center; width: 17px; height: 17px;
               border-radius: 50%; background: var(--ft-bg-muted);
               border: 1px solid var(--ft-border-color); color: var(--ft-text-secondary);
               font-size: .66rem; font-variant-numeric: tabular-nums; vertical-align: middle; }

/* Badge da chamada de tool: icone da SKILL + nome + resultado + tamanho do payload. */
.ft-ai-call { display: inline-flex; align-items: center; gap: .4rem; padding: 2px 7px 2px 4px;
              border: 1px solid var(--ft-border-color); border-radius: 99px;
              background: var(--ft-bg-surface); font-size: .72rem; }
.ft-ai-call--err { border-color: var(--ft-color-danger); }
.ft-ai-call__ico { display: grid; place-items: center; width: 17px; height: 17px;
                   border-radius: 50%; background: var(--ft-bg-muted); color: var(--ft-text-secondary); }
.ft-ai-call__ico .ft-icon { width: 10px; height: 10px; }
.ft-ai-call__nm { font-family: ui-monospace, monospace; color: var(--ft-text-primary); }
.ft-ai-call__sk { color: var(--ft-text-muted); }
.ft-ai-call__sz { color: var(--ft-text-muted); font-variant-numeric: tabular-nums; }
.ft-ai-call__st { display: grid; place-items: center; }
.ft-ai-call__st .ft-icon { width: 11px; height: 11px; }
.ft-ai-call__st--ok { color: var(--ft-color-success); }
.ft-ai-call__st--err { color: var(--ft-color-danger); }
/* Icone da badge tingido pela identidade do token quando o item TEM um tipo — artefato e
   schema. Chamada de tool fica no cinza neutro: a cor ali significaria preco, e nao ha. */
.ft-ai-call__ico--input  { background: var(--ft-tok-input-bg); color: var(--ft-tok-input); }
.ft-ai-call__ico--output { background: var(--ft-tok-output-bg); color: var(--ft-tok-output); }
.ft-ai-call__ico--cwrite { background: var(--ft-tok-cache-write-bg); color: var(--ft-tok-cache-write); }
.ft-ai-call__ico--cread  { background: var(--ft-tok-cache-read-bg); color: var(--ft-tok-cache-read); }
.ft-ai-call__ico--gen    { background: var(--ft-bg-muted); color: var(--ft-text-secondary); }

/* Conteudo da linha do no: o botao do toggle e o container, entao o alinhamento mora aqui. */
.ft-ai-node { display: inline-flex; align-items: center; gap: 8px; }

/* O que sobra aqui e so o que e DESTA tela. As guias dos niveis aninhados foram para o
   tema (`ft-theme.css`, secao "Guias da arvore") e valem para toda arvore do sistema.

   ⚠️ A guia da RAIZ e local de proposito: aqui existe um cabecalho acima da arvore
   ("Como esta resposta foi montada") que faz as vezes de pai, entao o conector do primeiro
   nivel aponta para algo. Numa arvore sem esse cabecalho ele apontaria para o vazio — por
   isso o tema nao desenha a raiz.

   ⚠️ O `width: auto` na folha tambem fica aqui: o tema da `width: 100%` a ela para o
   hover cobrir a linha toda, o que as outras arvores querem. Esta nao tem espacador nem
   hover, entao a largura cheia so afastaria a badge da guia. */
.ft-ai-tree { padding-left: 1.05rem; }
/* Mesma razao do leaf: o tema da width 100% ao toggle para o hover cobrir a linha toda.
   Aqui o botao divide a linha com a barra de mistura, entao ele so pode ocupar o que precisa
   — senao empurra a barra para fora. O alvo de clique passa a ser a seta mais a bola. */
.ft-ai-tree .ft-tree__toggle { width: auto; }
.ft-ai-tree .ft-tree__leaf { width: auto; padding-left: 0; }
.ft-ai-tree .ft-tree__leaf:hover { background: transparent; }

.ft-ai-tree > .ft-tree__item { position: relative; }
/* Mesmo motivo da guia aninhada no tema: `.ft-tree` tambem e grid com gap, e a raiz
   picotava igual. */
.ft-ai-tree > .ft-tree__item::before { content: ""; position: absolute; left: -0.62rem;
                                       top: 0; bottom: calc(-1 * var(--ft-space-1));
                                       width: 1px; background: var(--ft-border-color); }
.ft-ai-tree > .ft-tree__item:last-child::before { bottom: auto; height: 1rem; }
.ft-ai-tree > .ft-tree__item::after { content: ""; position: absolute; left: -0.62rem;
                                      top: 1rem; width: 0.5rem; height: 1px;
                                      background: var(--ft-border-color); }
.ft-ai-trace__err { flex: 1 1 100%; color: #b42318; white-space: pre-wrap; }
.ft-ai-composer { display: flex; gap: .5rem; align-items: flex-end; }
.ft-ai-composer .ft-input { flex: 1 1 auto; resize: none; }

/* ---------- Anexos (Fase 19) ----------
   Chips acima do campo, e não dentro do .ft-ai-composer: ali disputariam o flex com o textarea e o
   campo encolheria a cada anexo. Todo var() leva fallback — o tema não tem classe de chip, então estas
   regras são locais da tela e não podem depender de token que talvez não exista. Os --ft-chat-* não precisam:
   moram no topo deste arquivo. */
.ft-ai-attachments { display: flex; flex-wrap: wrap; gap: .4rem; padding: 0 .1rem .4rem; }
.ft-ai-chip { display: inline-flex; align-items: center; gap: .35rem; max-width: 18rem;
              padding: .2rem .5rem; border-radius: var(--ft-chat-chip-radius); font-size: .78rem;
              background: var(--ft-chat-chip-bg);
              border: var(--ft-chat-chip-border); }
.ft-ai-chip__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ft-ai-chip__meta { color: var(--ft-text-muted, #667085); flex: none; }
.ft-ai-chip__remove { border: 0; background: none; cursor: pointer; line-height: 1;
                      padding: 0 .1rem; color: var(--ft-text-muted, #667085); }
.ft-ai-chip__remove:hover { color: var(--ft-color-danger, #d92d20); }
/* Alvo do arrastar: a moldura pontilhada é o único sinal de que soltar ali funciona. */
.ft-ai-composer--drop { outline: 2px dashed var(--ft-color-primary, #0d6efd); outline-offset: 3px; }
/* Chips dentro de uma mensagem já enviada: mesma pastilha, sem o botão de remover. */
.ft-ai-msg__attachments { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .4rem; }
.ft-ai-chip__name { cursor: pointer; text-decoration: underline dotted; }

/* ---------- Pré-visualização do anexo ----------
   `vh` e não `%`: a modal se dimensiona pelo conteúdo, então uma altura relativa aqui colapsaria para
   zero no iframe (pai sem altura definida) e o PDF apareceria como uma faixa fina. */
.ft-ai-preview { max-height: 74vh; overflow: auto; }
.ft-ai-preview__img { max-width: 100%; height: auto; display: block; margin: 0 auto; }
.ft-ai-preview__frame { width: 100%; height: 70vh; border: 0; }
.ft-ai-preview__text { max-height: 70vh; overflow: auto; margin: 0; white-space: pre-wrap;
                       word-break: break-word; font-size: .8rem;
                       background: var(--ft-bg-subtle, #f2f4f7); padding: .6rem; border-radius: 6px; }

/* ---------- Relato em tempo real ----------
   Uma linha só, discreta, acima do campo. `aria-live` no markup para leitor de tela anunciar. */
.ft-ai-progress { display: flex; align-items: center; gap: .5rem; padding: .35rem .1rem .5rem;
                  font-size: .8rem; color: var(--ft-text-muted, #667085); }
/* Os tres pontinhos que viviam aqui (.ft-ai-progress__dots + @keyframes ft-ai-blink) sairam em
   2026-09-21: quem sinaliza o trabalho nesta linha agora e o assistente em `is-working`, que ja traz a
   propria animacao e o proprio tratamento de prefers-reduced-motion. */
.ft-ai-progress .assistant { flex: none; }

/* ---------- Trilho de conversas ----------
   A largura vem de --ft-ai-rail, escrita pelo JS a partir da preferência do usuário (banco, nunca
   localStorage). Recolhido, o trilho vira uma coluna de ícones — e é por isso que cada conversa tem um
   ícone gerado: sem ele o modo recolhido seria uma pilha de quadrados iguais. */
/* ALTURA FIXA é o que joga a rolagem para DENTRO das colunas: sem ela o grid cresce, a página
   inteira rola e o campo de texto vai embora junto. A altura vem do JS (fitApp), que mede a distância
   real até o topo — assim a barra de menu pode mudar de altura sem quebrar a conta. O valor abaixo é
   só o palpite inicial, antes da primeira medição. */
.ft-ai-app { display: grid; grid-template-columns: var(--ft-ai-rail, 272px) 10px minmax(0, 1fr);
             align-items: stretch; height: var(--ft-ai-h, calc(100dvh - 220px)); min-height: 380px; }
.ft-ai-app.is-collapsed { --ft-ai-rail: 60px; }
@media (max-width: 860px) {
    .ft-ai-app { grid-template-columns: minmax(0, 1fr); }
    .ft-ai-split { display: none; }
}

/* Raio 24: o mesmo arredondado do painel ao lado (redesenho de 2026-09-23 — só visual, os dados do
   trilho não mudaram). */
.ft-ai-rail { display: flex; flex-direction: column; min-height: 0; overflow: hidden; border-radius: 24px; }
/* Duas linhas: titulo+acoes em cima, medidor da janela embaixo. O medidor entra AQUI, e nao
   solto acima da busca, para ficar dentro da mesma moldura do cabecalho — solto ele lia como
   mais um filtro da lista. */
.ft-ai-rail__head { display: grid; gap: .5rem;
                    padding: .75rem; border-bottom: 1px solid var(--ft-border-color); }
.ft-ai-rail__headtop { display: flex; align-items: center; justify-content: space-between; gap: .5rem; }
.ft-ai-rail__title { margin: 0; font-size: .875rem; font-weight: 600; }
.ft-ai-rail__headacts { display: flex; gap: .15rem; }
.ft-ai-rail__search { padding: .5rem .5rem 0; }
.ft-ai-rail__search .ft-input { width: 100%; }
.ft-ai-rail__list { display: grid; gap: 2px; padding: .5rem; overflow-y: auto; min-height: 120px; }
.ft-ai-rail__foot { margin-top: auto; padding: .5rem .75rem .75rem; display: grid; gap: .5rem;
                    border-top: 1px solid var(--ft-border-color); }
.ft-ai-rail__count { font-size: .75rem; color: var(--ft-text-muted); }
.ft-ai-rail__new { justify-content: center; border-radius: 999px; }
.ft-ai-empty { font-size: .8rem; color: var(--ft-text-muted); padding: .5rem .25rem; }

.ft-ai-iconbtn { padding: .3rem; border: 1px solid transparent; border-radius: var(--ft-radius-sm);
                 background: none; color: var(--ft-text-muted); line-height: 0; }
.ft-ai-iconbtn:hover { background: var(--ft-bg-muted); color: var(--ft-text-primary); }
.ft-ai-iconbtn[aria-pressed="true"] { background: var(--ft-bg-muted); color: var(--ft-text-primary); }

/* ⚠️ A linha é um <div>, e só a ÁREA DE ABRIR é <button>. Os ícones de ação são IRMÃOS dele, nunca
   filhos: <button> não aceita conteúdo interativo, e aninhar botão em botão faz o browser tratar a linha
   como um alvo só — o clique no ícone nunca chega, e nenhum stopPropagation resolve, porque não há
   evento a parar. */
.ft-ai-conv { display: grid; grid-template-columns: minmax(0,1fr) auto; align-items: center;
              gap: .15rem; border: 1px solid transparent; border-radius: var(--ft-radius-md); }
.ft-ai-conv:hover { background: var(--ft-bg-muted); }
.ft-ai-conv.is-current { background: var(--ft-bg-muted); border-color: var(--ft-border-color); }
.ft-ai-conv__open { display: grid; grid-template-columns: auto minmax(0,1fr); align-items: center;
                    gap: .5rem; padding: .5rem; width: 100%; min-width: 0; cursor: pointer;
                    text-align: left; background: none; border: 0; font: inherit; color: inherit;
                    border-radius: var(--ft-radius-md); }
.ft-ai-conv__open:focus-visible { outline: 0; box-shadow: 0 0 0 .2rem var(--ft-focus-ring); }
.ft-ai-conv__ico { width: 1.75rem; height: 1.75rem; flex: none; display: grid; place-items: center;
                   border: 1px solid var(--ft-border-color); border-radius: var(--ft-radius-sm);
                   background: var(--ft-bg-surface); color: var(--ft-text-secondary); }
.ft-ai-conv__ico .ft-icon { width: .95rem; height: .95rem; }
.ft-ai-conv.is-current .ft-ai-conv__ico { background: var(--ft-color-primary);
                                          border-color: transparent; color: #fff; }
.ft-ai-conv__txt { min-width: 0; }
.ft-ai-conv__t { margin: 0; font-size: .875rem; white-space: nowrap; overflow: hidden;
                 text-overflow: ellipsis; }
.ft-ai-conv__d { margin: 0; font-size: .72rem; color: var(--ft-text-muted); }
.ft-ai-conv__acts { display: flex; gap: 2px; padding-right: .35rem; opacity: 0; }
.ft-ai-conv:hover .ft-ai-conv__acts, .ft-ai-conv:focus-within .ft-ai-conv__acts { opacity: 1; }

/* Removida: riscada e em tom de erro — o estado tem de ser óbvio, senão o usuário acha que sumiu. */
.ft-ai-conv.is-removed { background: var(--ft-bg-danger-subtle); }
.ft-ai-conv.is-removed .ft-ai-conv__t { text-decoration: line-through; color: var(--ft-text-muted); }
.ft-ai-conv.is-removed .ft-ai-conv__ico { opacity: .55; }

.ft-ai-app.is-collapsed .ft-ai-conv { grid-template-columns: auto; }
.ft-ai-app.is-collapsed .ft-ai-conv__open { grid-template-columns: auto; justify-items: center; }
.ft-ai-app.is-collapsed .ft-ai-conv__txt,
.ft-ai-app.is-collapsed .ft-ai-conv__acts,
.ft-ai-app.is-collapsed .ft-ai-rail__title,
.ft-ai-app.is-collapsed .ft-ai-window,
.ft-ai-app.is-collapsed .ft-ai-rail__search,
.ft-ai-app.is-collapsed .ft-ai-rail__count,
.ft-ai-app.is-collapsed .ft-ai-rail__newlabel { display: none; }

/* Divisor: alvo largo para o mouse, traço fino para o olho. */
.ft-ai-split { cursor: col-resize; display: flex; align-items: center; justify-content: center;
               background: none; border: 0; padding: 0; }
.ft-ai-split::before { content: ""; width: 2px; height: 44px; border-radius: 2px;
                       background: var(--ft-border-color); transition: height .12s, background .12s; }
.ft-ai-split:hover::before, .ft-ai-split:focus-visible::before { background: var(--ft-color-primary);
                                                                height: 64px; }
.ft-ai-split:focus-visible { outline: 0; }
.ft-ai-app.is-collapsed .ft-ai-split { cursor: default; }
@media (prefers-reduced-motion: reduce) { .ft-ai-split::before { transition: none; } }

/* Raio 28: o painel do redesenho (tela cheia). Com o palco 3D à direita, ft-assistant.css reta o lado dele. */
.ft-ai-main { display: flex; flex-direction: column; min-width: 0; min-height: 0; overflow: hidden;
              border-radius: 28px; }
/* O corpo é a coluna que distribui: log cresce e rola, compositor fica ancorado no fim. */
.ft-ai-main > .assistant-conv__body { display: flex; flex-direction: column; min-height: 0; flex: 1 1 auto;
                                 overflow: hidden; }
.ft-ai-main > .assistant-conv__head { flex: none; }
/* Chip de custo: a UNICA faixa do chat que nunca se move. O compositor ja tem a linha de progresso, que
   aparece e some a cada turno — medidor de orcamento que pula de lugar as pessoas param de ler.

   ⚠️ Mostra SO o custo desta conversa. O orcamento da janela e outro assunto e mora no trilho:
   os dois no mesmo chip faziam ler o gasto do periodo como se fosse desta conversa — e o numero
   da janela nem muda quando se troca de conversa, o que tornava o chip inteiro confuso. */
.ft-ai-cost { display: flex; align-items: center; gap: .4rem; font-size: .78rem;
              color: var(--ft-text-muted); font-variant-numeric: tabular-nums; white-space: nowrap; }

/* Medidor da janela — segunda linha do cabecalho do trilho, colado nas conversas porque e o
   gasto de TODAS elas no periodo, nao o da que esta aberta.
   Aqui a barra tem teto: o preenchimento e a fracao gasta e o vazio quer dizer "ainda cabe".
   Larga de proposito, e sem numero ao lado — e o unico lugar da tela onde a proporcao do
   orcamento aparece, e proporcao pequena em barra estreita nao se le. Os valores estao no hover.

   ⚠️ UMA LINHA POR PLANO. Com dois creditos, uma barra so respondia "quanto sobrou" sem dizer de
   qual conta — e era justamente a do plano da conversa aberta, entao a outra ficava invisivel. Cada
   linha leva o nome da regra e a cor do credito (--ft-credit-*, a MESMA do painel). */
.ft-ai-window { display: flex; flex-direction: column; gap: 4px;
                font-size: .72rem; color: var(--ft-text-muted); }
.ft-ai-window__label { flex: none; }
.ft-ai-window__rows { display: flex; flex-direction: column; gap: 4px; }
.ft-ai-wrow { display: flex; align-items: center; gap: .4rem; }
.ft-ai-wrow--shared { --win: var(--ft-credit-shared); }
.ft-ai-wrow--own    { --win: var(--ft-credit-own); }
.ft-ai-wrow__dot { flex: none; width: .5rem; height: .5rem; border-radius: 50%;
                   background: var(--win); }
/* Largura fixa no nome: sem ela a barra de cada linha comecaria num ponto diferente e as duas
   proporcoes deixariam de ser comparaveis de relance, que e a unica coisa que esta faixa faz. */
.ft-ai-wrow__name { flex: 0 0 6.5em; display: flex; align-items: center; gap: .3rem; min-width: 0; }
.ft-ai-wrow__txt { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 400; }
.ft-ai-wrow--current .ft-ai-wrow__txt { color: var(--ft-text-primary); font-weight: 600; }
.ft-ai-wrow__slot { flex: 1 1 auto; min-width: 0; }
.ft-ai-wrow__slot .ft-mixbar { display: block; width: auto; }
.ft-ai-wrow--warn .ft-mixbar__track { border-color: var(--ft-color-warning); }
.ft-ai-wrow--over .ft-mixbar__track { border-color: var(--ft-color-danger); }
.ft-ai-wrow--over .ft-ai-wrow__txt { color: var(--ft-color-danger); font-weight: 600; }

/* Quem paga esta conversa. Fica no cabeçalho, ao lado do custo, porque é a mesma pergunta vista de
   dois ângulos: "quanto" e "de quem". Combo enquanto a conversa é nova; rótulo fixo depois. */
.ft-ai-mainhead { display: flex; align-items: center; gap: .75rem; min-width: 0; }
.ft-ai-plan { display: flex; align-items: center; gap: .35rem; min-width: 0;
              font-size: .78rem; color: var(--ft-text-muted); }
.ft-ai-plan .ft-icon { width: .85rem; height: .85rem; flex: none; }
.ft-ai-plan__fixed { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Seletividade dupla de propósito: `.ft-select` nasce `width:100%` e `min-height:2.5rem`, o que no
   cabeçalho empurraria o chip de custo para fora. Empatar em `.ft-ai-plan__pick` dependeria da ordem
   dos arquivos de estilo. */
.ft-ai-plan .ft-ai-plan__pick { width: auto; max-width: 16rem; min-height: 1.9rem;
                                padding: .1rem .4rem; font-size: .78rem; }

/* Compositor bloqueado: conversa removida é para LER. */
.ft-ai-removed-notice { display: flex; align-items: center; gap: .75rem; flex-wrap: wrap;
                        margin-top: 1rem; padding: .6rem .75rem; font-size: .875rem;
                        border: 1px solid var(--ft-color-danger); border-radius: var(--ft-radius-md);
                        background: var(--ft-bg-danger-subtle); }

/* Gravação de áudio */
.ft-ai-mic { width: 2.6rem; height: 2.6rem; padding: 0; justify-content: center; flex: none; }
.ft-ai-rec__box { display: flex; align-items: center; gap: .5rem; flex: 1 1 auto; min-height: 2.6rem;
                  padding: .5rem .75rem; font-size: .875rem;
                  border: 1px solid var(--ft-color-danger); border-radius: var(--ft-radius-md);
                  background: var(--ft-bg-danger-subtle); }
.ft-ai-rec__dot { width: .5rem; height: .5rem; border-radius: 50%; flex: none;
                  background: var(--ft-color-danger); animation: ftAiPulse 1.4s ease-in-out infinite; }
.ft-ai-rec__wave { display: flex; align-items: center; gap: 2px; height: 1rem; flex: 1 1 auto; }
.ft-ai-rec__wave i { display: block; width: 3px; border-radius: 2px;
                    background: var(--ft-color-danger); opacity: .65; }
.ft-ai-rec__time { font-variant-numeric: tabular-nums; color: var(--ft-text-muted); }
@keyframes ftAiPulse { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }
@media (prefers-reduced-motion: reduce) { .ft-ai-rec__dot { animation: none; } }

/* ---------- Modo MODAL (/Ai/Panel dentro de um iframe) ----------
   O trilho é renderizado e ESCONDIDO, não omitido: o script tem ~79 referências a elementos dele,
   várias sem guarda de nulo, e um só script servindo os dois lugares vale mais que o markup poupado.
   Ver o comentário de `_FtAiChatRail.cshtml`. */
.ft-ai-app--modal > .ft-ai-rail,
.ft-ai-app--modal > .ft-ai-split { display: none; }
.ft-ai-app--modal { grid-template-columns: 1fr; height: 100%; }
/* Dentro do iframe a altura é a da janela dele, não a do `--ft-ai-h` medido na tela cheia. */
.ft-ai-embed, .ft-ai-embed body { height: 100%; }
.ft-ai-embed .ft-ai-app { --ft-ai-h: 100%; height: 100%; }
/* Na modal quem desenha o card é o `.ft-ai-app--modal` (ft-assistant.css › "MODAL"): o painel fica sem
   moldura E sem fundo — fundo próprio aqui pintaria cantos retos por cima dos cantos arredondados dele. */
.ft-ai-embed .ft-ai-main { border-radius: 0; border: 0; background: transparent; box-shadow: none; }
