/* Dotti Studio — as quatro telas novas do Robô (Ajustes, Avatares, Canais, Custos).
 *
 * ARQUIVO SEPARADO, e isso é temporário e declarado: o `estilo.css` da casa
 * está sendo editado por outra frente agora, e duas mãos no mesmo arquivo é
 * conflito garantido. Nada aqui inventa cor, fonte ou raio — tudo sai dos
 * tokens de `:root` do `estilo.css`, então o tema claro/escuro continua
 * mandando. Quando o arquivo grande liberar, isto vira um bloco lá dentro sem
 * mudar um pixel.
 */

/* ------------------------------------------------------------- ajustes -- */

/* `auto-fill` e não `repeat(N, …)`: grade de quantidade variável com número
   fixo de colunas joga metade da largura fora num monitor largo. É a mesma
   lição que o mapa de beats do painel já pagou. */
.ajustes-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 16px;
  /* Sem isto, cada campo estica até a altura da linha e o campo mais alto (a
     escolha em cartões) abre um vazio de ~300 px sob os vizinhos. Visto no
     navegador; nenhum teste de string mostraria. */
  align-items: start;
}

/* Campo alto ocupa a LINHA INTEIRA. Meia largura para três cartões de opção
   empilhados deixa a metade ao lado permanentemente vazia — e é justamente o
   campo cujo texto de ajuda (o preço do vídeo de IA) precisa ser lido. */
.ajustes-grid > .campo-ajuste:has(.opcoes-cartao),
.ajustes-grid > .campo-ajuste:has(textarea) { grid-column: 1 / -1; }

.campo-ajuste { display: flex; flex-direction: column; gap: 6px; }
.campo-ajuste > label {
  font-family: var(--mono); font-size: 0.7188rem; letter-spacing: .14em;
  text-transform: uppercase; color: var(--texto3);
  display: flex; align-items: baseline; gap: 8px;
}

/* O selo "no padrão" HERDAVA o uppercase e o letter-spacing do rótulo, e o
   resultado era lido como parte dele: "VOZ DO GENAI PRO (VOICE_ID) NO PADRÃO".
   Ele diz uma coisa sobre o campo, não é o nome do campo — então tem de
   parecer outra coisa. */
.campo-ajuste > label .no-padrao {
  text-transform: none; letter-spacing: 0; font-size: 0.6875rem;
  padding: 1px 6px; border-radius: 999px;
  border: 1px solid var(--linha2); color: var(--texto3);
}
.campo-ajuste input[type="text"],
.campo-ajuste input[type="number"],
.campo-ajuste select,
.campo-ajuste textarea {
  background: var(--sup2); border: 1px solid var(--linha2); border-radius: 8px;
  color: var(--texto); padding: 9px 11px; font: inherit; font-size: 0.875rem;
  width: 100%;
}
/* O `<select>` nativo não herda nada e vinha branco, apertado e com o texto da
   opção cortado no meio ("Avatar IV … ~US$"). `text-overflow` não funciona em
   select: o que resolve é a caixa ter a largura toda e a fonte não estourar. */
.campo-ajuste select { appearance: none; cursor: pointer; padding-right: 28px; }
.campo-ajuste textarea { resize: vertical; min-height: 68px; line-height: 1.45; }
.campo-ajuste input:focus, .campo-ajuste textarea:focus {
  outline: none; border-color: var(--azul); background: var(--sup3);
}
.campo-ajuste .dica { margin: 0; }

/* A opção em cartão existe para a CONSEQUÊNCIA de cada escolha caber na tela.
   Num `<select>`, "vídeo de IA custa muito mais que imagem" fica escondido
   atrás de um clique — e é justamente essa a frase que evita a fatura de
   surpresa. */
.opcoes-cartao { display: flex; flex-direction: column; gap: 7px; }
.opcao-cartao {
  display: flex; align-items: flex-start; gap: 9px; cursor: pointer;
  border: 1px solid var(--linha2); border-radius: 8px; padding: 9px 11px;
  background: var(--sup2);
}
.opcao-cartao:hover { border-color: var(--linha2); background: var(--sup3); }
.opcao-cartao:has(input:checked) {
  border-color: var(--azul);
  background: color-mix(in srgb, var(--azul) 8%, transparent);
}
.opcao-cartao input { margin-top: 3px; accent-color: var(--azul); }
.opcao-cartao span { display: flex; flex-direction: column; gap: 2px; }
.opcao-cartao b { font-size: 0.875rem; font-weight: 600; }
.opcao-cartao small { color: var(--texto3); font-size: 0.75rem; }

/* Opção que a conta não entrega: apagada e sem cursor de clique, mas LEGÍVEL —
   ela existe para a pessoa saber que a decisão existe. O motivo fica na cor de
   aviso, porque ele é a informação nova da linha. */
.opcao-cartao.desativada { opacity: .55; cursor: not-allowed; }
.opcao-cartao.desativada input { cursor: not-allowed; }
.opcao-cartao .motivo { color: var(--amarelo); }

.opcoes-caixa { display: flex; flex-wrap: wrap; gap: 7px 14px; }
.opcao-caixa {
  display: flex; align-items: center; gap: 7px; cursor: pointer;
  font-size: 0.875rem;
}
.opcao-caixa input { accent-color: var(--azul); }

.avancado {
  border: 1px solid var(--linha); border-radius: var(--r); padding: 12px 14px;
  background: var(--sup);
}
.avancado > summary {
  min-height: 36px; display: flex; align-items: center;
  cursor: pointer; font-family: var(--mono); font-size: 0.75rem;
  letter-spacing: .12em; text-transform: uppercase; color: var(--texto2);
}
.avancado[open] > summary { margin-bottom: 12px; }

.chaves-linhas { display: flex; flex-direction: column; gap: 6px; }
.chave-linha {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 6px 8px; border-radius: 6px; background: var(--sup2);
}
.chave-linha .dica { flex: 1 1 100%; }

/* ------------------------------------------------- avatares e canais -- */

.cartoes {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 13px;
}
/* `display: block`, e NÃO flex-column.
 *
 * Medido no navegador: com o cartão em coluna flex, o retrato saía com 277 px
 * de largura e **38 px** de altura — a altura do emoji — apesar de
 * `aspect-ratio: 1/1` estar computado corretamente. Item flex com
 * `flex-basis: auto` tem a altura decidida pelo CONTEÚDO, e o `aspect-ratio`
 * só entra quando uma das dimensões é indefinida. `flex: none` não conserta
 * (foi a primeira tentativa e não mudou nada). Fora do flex, ele funciona. */
.cartao-avatar {
  border: 1px solid var(--linha); border-radius: var(--r); overflow: hidden;
  background: var(--sup); display: block;
}
/* `.foto-do-avatar` e NAO `.retrato`: a casa JA' TEM uma `.retrato` — o avatar
   redondo de 38x38 do usuario, no topo e nos cartoes de perfil. A minha regra
   sobrescrevia `width` e `aspect-ratio` e nao `height`, entao o `height: 38px`
   dela continuava valendo: a foto saia com 277 px de largura por 38 de altura.
   Medido no navegador, depois de duas tentativas erradas (`flex: none` e
   `display: block` no cartao) — o defeito nao estava no meu flex, estava no
   nome. Classe nova em folha compartilhada precisa de nome que nao exista. */
.cartao-avatar .foto-do-avatar {
  aspect-ratio: 1 / 1; width: 100%; object-fit: cover; background: var(--sup3);
  display: flex; align-items: center; justify-content: center;
  color: var(--texto3); font-size: 2rem;
  /* Sem `flex: none` o retrato encolhe até virar uma tarja de ~40 px: ele é um
     item flex numa coluna, e o `aspect-ratio` perde para o shrink. */
  flex: none;
}
.cartao-avatar .corpo {
  padding: 10px 12px; display: flex; flex-direction: column; gap: 6px;
  /* Os filhos são chips e textos curtos. Sem isto o `stretch` do flex os
     estica pela largura toda, e o chip "não verificado" vira uma caixa que se
     lê como campo de formulário. */
  align-items: flex-start;
}
.cartao-avatar .rb-nome { font-weight: 600; font-size: 0.9375rem; }

.linha-canal {
  border: 1px solid var(--linha); border-radius: var(--r); background: var(--sup);
  padding: 12px 14px; display: flex; flex-direction: column; gap: 8px;
}
.linha-canal .resumo { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.linha-canal .resumo b { font-size: 0.9375rem; }
.linha-canal .resumo .dica { margin: 0; }

/* --------------------------------------------------------------- custos -- */

.rb-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 12px; }
.rb-tile {
  border: 1px solid var(--linha); border-radius: var(--r); background: var(--sup);
  padding: 12px 14px; display: flex; flex-direction: column; gap: 4px;
}
.rb-tile .rb-rot {
  font-family: var(--mono); font-size: 0.6875rem; letter-spacing: .14em;
  text-transform: uppercase; color: var(--texto3);
}
.rb-tile .rb-val { font-family: var(--display); font-size: 1.5rem; font-weight: 600; }
/* "sem base" é estado de primeira classe: um zero no lugar dele se lê como
   "de graça", que é uma afirmação diferente e provavelmente falsa. */
.rb-tile .rb-val.sembase { color: var(--texto3); font-size: 1.125rem; }

/* Tabela larga rola DENTRO do próprio contêiner; o corpo da página nunca rola
   na horizontal. */
.rb-rolagem { overflow-x: auto; }
.tabela { width: 100%; border-collapse: collapse; font-size: 0.8125rem; }
.tabela th {
  text-align: left; font-family: var(--mono); font-size: 0.6875rem;
  letter-spacing: .1em; text-transform: uppercase; color: var(--texto3);
  padding: 7px 10px; border-bottom: 1px solid var(--linha); white-space: nowrap;
}
.tabela td { padding: 8px 10px; border-bottom: 1px solid var(--linha); white-space: nowrap; }
.tabela td.num { text-align: right; font-family: var(--mono); }
.tabela tr:hover td { background: var(--sup); }


/* ══════════════════════════════════════════════════════════════════════════
   P1 · BASE + O PEDIDO — a pintura do mockup entra aqui
   Fonte: research/conveyer-e-ytfill/robo-mockup.html, <style> linhas 3-246.
   Cada valor abaixo foi LIDO daquele arquivo, não lembrado.

   O mockup foi consumido como referência de ESTRUTURA (a barra em duas
   famílias, a legenda) e nunca como referência de PINTURA — nenhum token dele
   existia neste repositório. A ordem do dono é *"precisa ser igual ao mockup"*,
   e ela está tomada: eu levantei que a paleta dele desalinha o Robô do resto do
   Dotti, e ele reafirmou.

   ESCOPADO NA TELA DO ROBÔ, nunca no `:root`. O mockup só descreve o Robô — ele
   não faz afirmação nenhuma sobre login, checkout ou aulas, e repintá-los seria
   mudança que ninguém pediu.

   CONSEQUÊNCIA DECLARADA, e ela é real: a paleta do mockup é escura e o site
   tem tema CLARO (`:root[data-tema="claro"]`). Como os tokens são redefinidos
   aqui com valor FIXO, a tela do Robô fica escura NOS DOIS TEMAS. Isso segue do
   pedido — o mockup é uma paleta só —, não é descuido, e é o tipo de coisa que
   tem de estar escrita antes de alguém descobrir clicando.
   ══════════════════════════════════════════════════════════════════════════ */

.robo-raiz {
  /* --- os tokens do mockup, ipsis litteris (linhas 4-15 do arquivo) --- */
  --ground: #0b0b0d;  --surf: #141417;  --surf2: #1c1c20;  --surf3: #232329;
  --line: #2a2a30;    --line-soft: #202026;
  --ink: #e8e8ea;     --dim: #8e8e96;   --faint: #5f5f68;
  --red: #e5202f;     --red-soft: #3a1013;
  --ok: #3fb950;      --ok-soft: #0f2716;
  --warn: #d29922;    --warn-soft: #2b2110;
  --bad: #f85149;     --bad-soft: #2d1416;
  /* A TIPOGRAFIA DO ROBO E A DA CASA — Geist e Geist Mono.
     Este bloco declarava fontes PROPRIAS: `Inter` como sans e a mono do
     sistema. Eram 44 pontos (34 `var(--mono)` + 10 `var(--sans)`) desenhando o
     Robo inteiro com outra letra, dentro de um app cujo briefing fixa "Geist e
     Geist Mono" e cujo DESIGN.md reserva a Geist Mono justamente para
     procedencia, sequencia, horario e dado tabular. Medido no app rodando: o
     horario do log saia em `ui-monospace`, nao em Geist Mono.

     `--mono` SOME daqui, em vez de ser reescrita com o valor certo: o `:root`
     do estilo.css ja a declara (linha 65), e uma segunda copia do mesmo valor
     e a deriva que este repo ja catalogou — some a sobreposicao e a da casa
     volta a cascatear sozinha.
     `--sans` PRECISA ficar, porque a casa nao tem variavel com esse nome: ela
     passa a apontar para `--corpo`, que e a Geist do corpo de texto. */
  --sans: var(--corpo);
  --r: 6px;

  /* --- e o REMAPEAMENTO dos tokens da casa, que é o que faz isto funcionar ---
   *
   * Sem estas linhas, declarar os tokens do mockup não pintaria quase nada: as
   * ~107 regras `rb-*` que já estão no `estilo.css` (o log, as fases, o pulso,
   * as máquinas, as abas) continuariam lendo `--sup`, `--linha`, `--texto3` e
   * saindo com a paleta do site. Reescrever regra por regra seria mexer em
   * dezenas de seletores para trocar cor — muito mais superfície, e cada uma
   * uma chance de errar. Aqui a troca é no token, num lugar só, e QUALQUER
   * regra existente segue junto.
   *
   * Duas escolhas de mapeamento que NÃO são óbvias e por isso estão escritas:
   *
   *   --linha2 -> --line  (e NÃO --line-soft). Na casa, `--linha2` é mais CLARA
   *     que `--linha` (#3f3f3f contra #303030) e é a borda de campo; no mockup
   *     `--line-soft` é mais ESCURA que `--line` e é a divisória de linha de
   *     tabela. Mapear pelo nome inverteria a relação e o campo de texto ficaria
   *     com borda mais apagada que o painel em volta.
   *
   *   --azul -> --red. O mockup não tem azul: o destaque, o foco e o link dele
   *     são vermelhos. Manter o azul da casa deixaria foco e ação com a cor de
   *     outro produto no meio de uma tela repintada.
   */
  --void: var(--ground);
  --sup: var(--surf);      --sup2: var(--surf2);   --sup3: var(--surf3);
  --linha: var(--line);    --linha2: var(--line);
  --texto: var(--ink);     --texto2: var(--dim);   --texto3: var(--faint);
  --marca: var(--red);     --marca-2: var(--red);  --marca-txt: var(--red);
  --sobre-marca: #fff;

  /* O ROBO NAO SEGUE O TEMA — E O CAMPO TEM DE ACOMPANHAR ESSA ESCOLHA.
     Este bloco remapeia `--texto` para `--ink` (#e8e8ea), um claro FIXO: as
     telas do Robo sao uma superficie escura propria em qualquer tema. Quando
     `--linhas-campo-fundo` passou a virar com o tema (para consertar os campos
     ilegiveis do resto do app), o fundo do campo aqui foi para branco enquanto
     o texto continuou claro — medido, 1,22:1 em /robo, /robo-maquina e
     /robo-custos no tema claro.

     Fixar o par DENTRO do Robo mantem o que ele sempre foi (14,8:1, escuro
     sobre escuro) e deixa o resto do app corretamente tematizado. Tornar o Robo
     inteiro sensivel ao tema e' outro trabalho: sao 22 pontos que leem
     `--faint` como corpo de texto, e mexer neles sem medir ja' foi reprovado. */
  --linhas-campo-fundo: #141619;
  --linhas-campo-marca: #838994;
  --azul: var(--red);      --amarelo: var(--warn); --erro: var(--bad);
  /* `--display` e `--corpo` NAO sao mais remapeados aqui.
     O remapeamento existia para forcar a fonte propria do Robo (Inter) sobre
     quem lia os tokens da casa. Agora que `--sans` E a fonte da casa, ele
     virou identidade — e pior: junto com `--sans: var(--corpo)` formava um
     CICLO (`--sans` -> `--corpo` -> `--sans`), que o CSS resolve como valor
     invalido. Medido: `--sans` voltava vazio no `.robo-raiz` e as 10
     declaracoes que a usam eram descartadas. */

  /* DE ONDE VEIO A CENA — quatro tons, e cada um significa UMA coisa.
     Vermelho é footage real por decisão do dono ("tudo que é footage real é
     vermelho"), e é significado e não enfeite: ela vem do YouTube.

     POR ISSO O CROMO NÃO É VERMELHO. Se a cor da fonte também pintasse barra,
     botão e "você está aqui", o olho passaria a procurar procedência onde só há
     moldura, e o placar deixaria de se ler de relance.

     E NUNCA `--azul` PARA O APRESENTADOR: dentro de `.robo-raiz` ele está
     remapeado para `var(--red)` na linha acima — o apresentador sairia
     vermelho, idêntico ao footage real, e o placar mentiria em silêncio. Daí um
     hex próprio. */
  --fonte-real: var(--red);
  --fonte-ia: #a371f7;
  /* O CLIPE GERADO TEM COR PROPRIA (0.1.42, dono: *"precisa ter uma separacao
     entre imagem de ia e video de ia"*). Mesma familia do roxo, temperatura
     diferente -- e' a mesma regra que separou `filmagem` de `foto` no lado
     real, do outro lado da taxonomia.

     MEDIDO, nao escolhido no olho: DeltaE 2000 contra os vizinhos da fita --
     ia parada 17,3 · avatar 25,6 · filmagem 42,8 · foto 44,2. O piso da casa
     e' 15 (as 4 cores dos atos ja' REPROVARAM com 12,6 e tiveram de ser
     re-escalonadas). Tres candidatos reprovaram nesta mesma medicao: malva
     7,1 · indigo 8,7 · ametista 11,5.

     O CLARO, e nao o roxo profundo (18,5, tambem aprovado): o painel e' escuro,
     e o clipe e' o item CARO (391 s de mediana contra 11 imagens por minuto) --
     o olho deve cair nele. E o roxo da imagem parada nao muda, entao nenhuma
     tela existente se altera. */
  --fonte-ia-video: #d0b0ff;
  --fonte-avatar: #4493f8;
  --fonte-cromo: var(--faint);

  /* AS DUAS MÍDIAS DO MATERIAL REAL. `--fonte-real` continua existindo para o
     placar do vídeo PRONTO, que soma as duas; ao vivo elas se separam, porque
     somá-las foi o que produziu o "33 reais" num vídeo com 13 clipes e 21
     fotos paradas. Mesma família de cor, temperatura diferente: filmagem é o
     vermelho da marca, foto é o mesmo calor rebaixado. */
  --fonte-filmagem: var(--red);
  --fonte-foto: #e08a45;
  /* AINDA EM DISPUTA NÃO GANHA COR, ganha TEXTURA. A cor aqui é uma escala de
     realidade; pintar o indeciso com um tom qualquer o colocaria dentro dessa
     escala, e dois vermelhos lado a lado — um significando ganho, outro
     significando talvez — leriam igual. */
  --risco-disputa: repeating-linear-gradient(-45deg,
    rgba(255,255,255,.20) 0 1.5px, transparent 1.5px 6px);

  background: var(--ground);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 14px;
  line-height: 1.55;
}

/* `.wrap` do mockup: `max-width:1240px; margin:0 auto; padding:28px 24px 80px`.
 *
 * A CONTA, porque ela não é o número do mockup e a diferença tem de ser
 * explicada: a moldura da casa (`.conteudo`) já dá `padding: 22px 24px 60px` em
 * volta desta tela. O horizontal já bate EXATAMENTE (24px), então repeti-lo
 * daria 48. O que falta é só a diferença vertical — 6px em cima, 20px embaixo —
 * e é isso que está aqui. Total: 28 e 80, os números do mockup.
 *
 * `.conteudo > .robo-raiz` NUNCA CASOU, e a coluna foi publicada sem aplicar
 * uma vez. A cadeia real tem um nó no meio (`app.js:664`):
 *
 *     .conteudo > div(flex column, gap 22) > .robo-raiz
 *                  |                          `- a tela, trocada em `lugar`
 *                  `- .cabeca ("Robô" + subtítulo)
 *
 * `.robo-raiz` é NETO, não filho. Duas consequências no conserto:
 *
 * (a) quem tem de ser limitado é o INVÓLUCRO, não a tela. Limitar só a tela
 *     deixaria o `.cabeca` em 96rem e a coluna em 1240 — título e conteúdo
 *     desalinhados, que é pior que os dois largos. No mockup o `h1` vive
 *     DENTRO do `.wrap`, e é isso que esta regra reproduz.
 * (b) `body:has(.robo-raiz) .conteudo > *` tem especificidade (0,2,0) contra
 *     (0,1,0) de `.conteudo > *`: ganha por especificidade, não por ordem de
 *     carregamento. O `<link>` daqui é injetado por JavaScript, então empatar
 *     e torcer pela ordem funciona até alguém trocar a ordem.
 *
 * Navegador sem `:has()` cai no 96rem do site: mais largo, nunca quebrado. */
body:has(.robo-raiz) .conteudo > * {
  max-width: 1240px;
}
/* SEM `margin-inline: auto` AQUI, e o motivo é mecânico: o invólucro é
 * `display:flex; flex-direction:column`, e margem automática no eixo cruzado
 * DESLIGA o `align-items: stretch` — o item passa a ter a largura do conteúdo.
 * Medido: com `auto`, esta coluna encolhia de 1232 para 183px. Quem centra é o
 * invólucro (o `margin-inline: auto` de `.conteudo > *`, que continua valendo);
 * aqui a tela só estica. O `max-width` fica como rede para o dia em que ela for
 * montada fora deste invólucro. */
.conteudo .robo-raiz {
  max-width: 1240px;
  padding: 6px 0 20px;
}

/* O CHÃO TAMBÉM É DO MOCKUP, E SEM ISTO FICA UMA EMENDA VISÍVEL.
 *
 * `.robo-raiz` é uma coluna de 1240px; a moldura em volta dela (`.conteudo`) é
 * do site e continua em `--void` (#0f0f0f). O `--ground` do mockup é #0b0b0d —
 * quatro pontos mais escuro. Num monitor largo isso não some: aparece como um
 * retângulo de tom diferente no meio da página, que se lê como bug de layout.
 *
 * `body:has(.robo-raiz)` é o menor escopo que resolve: pinta o chão SÓ nas
 * páginas que contêm a tela do Robô, e não toca em nenhuma outra. Repintar
 * `.conteudo` direto mudaria login, feed, cursos e checkout — mudança que
 * ninguém pediu. `:has()` já é usado neste mesmo arquivo (`.ajustes-grid >
 * .campo-ajuste:has(.opcoes-cartao)`), então não é dependência nova.
 *
 * Navegador sem `:has()` ignora a regra inteira e cai no chão do site: a tela
 * continua legível, só com a emenda. Degradação, não quebra. */
body:has(.robo-raiz) .conteudo { background: #0b0b0d; }

/* ------------------------------------------------------- primitivas -- */

/* `.lab` do mockup (linhas 64-68) -> o `label` do `.campo-ajuste`, que é o nome
   que já está em produção. O rótulo antigo era 0.7188rem/.14em; o do mockup é
   10.5px/.13em, e a distância até o campo é 6px (o `gap` do `.campo-ajuste` já
   dá isso). */
/* R4 EM AÇÃO, e ela me pegou: eu tinha escrito só `.campo-ajuste`, que é o nome
   das QUATRO telas de configuração. A tela **Produzir** usa outro — `.campo`
   (estilo.css:190-199), com `label`, `input` e `.ajuda`. Pintar só um deixaria
   metade do formulário com a tipografia velha. Abri os dois seletores. */
.robo-raiz .campo-ajuste > label,
.robo-raiz .campo > label,
.robo-raiz .lab {
  display: block;
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .13em;
  text-transform: uppercase; color: var(--dim);
  margin-bottom: 0;
}
.robo-raiz .campo-ajuste > label { display: flex; align-items: baseline; gap: 8px; }

/* `.fld` (69-75). Raio 6px vem do `--r` redefinido acima. */
.robo-raiz .campo-ajuste input[type="text"],
.robo-raiz .campo-ajuste input[type="number"],
.robo-raiz .campo-ajuste select,
.robo-raiz .campo-ajuste textarea,
.robo-raiz .campo input[type="text"],
.robo-raiz .campo input[type="number"],
.robo-raiz .campo select,
.robo-raiz .campo textarea,
.robo-raiz select.sel,
.robo-raiz .fld {
  width: 100%; background: var(--surf); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--r);
  padding: 9px 11px; font-family: inherit; font-size: 14px;
}
.robo-raiz .fld::placeholder,
.robo-raiz .campo-ajuste input::placeholder,
.robo-raiz .campo-ajuste textarea::placeholder { color: var(--faint); }

/* FOCO VISÍVEL É REQUISITO, NÃO ENFEITE — o mockup o declara em `.fld`, `.abre`
   e `.lnk` (vermelho) e no `.btn` (tinta). A regra da casa usa `:focus` e tira o
   `outline`; aqui ele volta, e em `:focus-visible`, que é o que não acende ao
   clicar com o mouse. */
.robo-raiz .fld:focus-visible,
.robo-raiz .campo-ajuste input:focus-visible,
.robo-raiz .campo-ajuste select:focus-visible,
.robo-raiz .campo-ajuste textarea:focus-visible,
.robo-raiz .campo input:focus-visible,
.robo-raiz .campo select:focus-visible,
.robo-raiz .campo textarea:focus-visible {
  outline: 2px solid var(--red); outline-offset: 1px;
}

/* `.hint` (76) -> `.dica` (config) e `.ajuda` (produzir), os dois nomes que já
   existem. `margin-top:6px`, 12px, `--faint`. */
.robo-raiz .dica,
.robo-raiz .campo .ajuda,
.robo-raiz .hint { color: var(--faint); font-size: 12px; margin: 6px 0 0; }
.robo-raiz .campo-ajuste .dica { margin: 0; }
/* `.campo` já tem `gap: 6px`; a margem em cima da ajuda somaria com ele. */
.robo-raiz .campo .ajuda { margin: 0; }

/* `.row` (77-80) — a grade de 18px que colapsa a 1 coluna em 820px. Ela não
   existia em produção; entra com o nome do mockup porque não há nome anterior
   para reusar. */
.robo-raiz .row { display: grid; gap: 18px; margin-bottom: 18px; }
.robo-raiz .row.two { grid-template-columns: 1fr 1fr; }
.robo-raiz .row.three { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 820px) {
  .robo-raiz .row.two, .robo-raiz .row.three { grid-template-columns: 1fr; }
}

/* `.card` (82-85): raio 8px FIXO, e não `--r` — o mockup usa 6px em campo e
   botão e 8px em cartão, tile e chave. Dois raios de propósito. */
.robo-raiz .card {
  background: var(--surf); border: 1px solid var(--line);
  border-radius: 8px; padding: 18px;
}

/* `.btn` / `.btn.ghost` (86-92). A casa tem `.btn` (fantasma) e `.btn.pri`
   (sólido, marca); o mockup tem `.btn` (sólido, vermelho) e `.btn.ghost`. Os
   dois vocabulários coexistem: `.pri` continua sendo a ação principal e ganha a
   pintura do `.btn` do mockup; o `.btn` sozinho ganha a do `.ghost`. Trocar o
   significado das classes seria mexer em comportamento — proibido neste passo. */
.robo-raiz .btn {
  font-family: inherit; font-size: 13.5px; font-weight: 560;
  border-radius: var(--r); padding: 10px 18px; cursor: pointer;
  background: transparent; color: var(--ink); border: 1px solid var(--line);
}
.robo-raiz .btn.pri,
.robo-raiz .btn.primario {
  background: var(--red); color: #fff; border: 0; font-weight: 560;
}
.robo-raiz .btn.ghost { background: transparent; color: var(--ink); border: 1px solid var(--line); }
.robo-raiz .btn:hover:not(:disabled) { background: var(--surf2); }
.robo-raiz .btn.pri:hover:not(:disabled) { background: var(--red); filter: brightness(1.12); }
.robo-raiz .btn:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
/* DESABILITADO NAO E' CLICAVEL, e o cursor tem de dizer isso.
   `.btn:disabled { cursor: progress }` do `estilo.css` e' (0,2,0) e empata com
   o `.robo-raiz .btn` da linha 445 -- que carrega depois e vence, devolvendo
   `pointer`. Efeito: dentro do robo, TODO botao desabilitado convida ao
   clique. O caso mais duradouro e' o "Em breve" da tela de maquinas, que
   nasce desabilitado e fica assim ate' a plataforma existir.
   (0,3,0) para nao empatar com nada -- mesmo remedio que este arquivo ja'
   aplica nas outras variantes atropeladas. */
.robo-raiz .btn:disabled { cursor: progress; }

/* AS DUAS VARIANTES QUE O `.btn` GENÉRICO ATROPELAVA — achado pelo P3, e ele
   estava certo: eu declarei `color: var(--ink)` no `.btn` e as duas regras da
   casa têm a MESMA especificidade (0,2,0), então esta folha, que carrega
   depois, ganhava.
   O efeito era mudo e caro: o "desconectar" de uma máquina (`robo.js:1126`,
   `btn pequeno perigo`) e o "Remover" de avatar, canal e chave perdiam o tom
   de perigo e viravam botão comum — um botão destrutivo com a mesma cara do
   botão ao lado é exatamente o defeito que a cor de perigo existe para
   impedir. Repare que isto NÃO é o mockup mandando: o mockup não tem botão
   destrutivo em tela nenhuma, então aqui não há valor dele para copiar. Uso o
   `--bad` e a borda `#5c2226` do `.note.bad`/`.pill.bad`, que é a linguagem que
   o próprio mockup usa para "isto é ruim". */
.robo-raiz .btn.perigo {
  color: var(--bad); border-color: #5c2226; background: transparent;
}
.robo-raiz .btn.perigo:hover:not(:disabled) { background: var(--bad-soft); }
.robo-raiz .btn.sec {
  background: var(--surf2); border-color: var(--line); color: var(--dim);
}
.robo-raiz .btn.sec:hover:not(:disabled) { background: var(--surf3); color: var(--ink); }

/* UM `<a>` VESTIDO DE BOTÃO — o "Baixar a música" da tela de Canais.
 *
 * Ele PRECISA ser âncora e não `<button>`: a faixa mora em outro domínio, e
 * quem manda o navegador salvar é o `Content-Disposition` da resposta — ou
 * seja, o download é uma NAVEGAÇÃO e não uma chamada de JavaScript. Só que o
 * `<a>` do navegador vem sublinhado, e ao lado dos dois "Baixar .txt" da mesma
 * tela (esses sim `<button class="btn sec">`) o sublinhado faria o terceiro
 * parecer outra espécie de controle.
 *
 * NENHUMA CLASSE NOVA, de propósito: `btn`, `sec` e `pequeno` já são reuso
 * declarado da casa, então isto não entra na conta de colisão com o
 * `estilo.css`. O `display: inline-flex` que alinha o rótulo também já vem de
 * lá — esta folha nunca redeclarou `display` no `.btn`. O que falta é só o
 * sublinhado, e o precedente é literal: o `estilo.css` escreve
 * `.th-lado a.btn { text-decoration: none; }` pelo mesmo motivo, na tela de
 * miniaturas. Aqui vale para a `.robo-raiz` inteira, porque o próximo `<a>`
 * vestido de botão destas telas vai querer exatamente a mesma coisa. */
.robo-raiz a.btn { text-decoration: none; }

/* O ESTADO DE UMA LINHA — `.pill` no mockup (94-103), `.chip` em produção.
 *
 * DUAS DECISÕES QUE SE CORRIGIRAM NO MEIO DO CAMINHO, e a história importa mais
 * que o resultado. Eu criei `.pill` porque era o nome do mockup e o §2 o
 * listava como novo. Só que **ninguém emite `.pill`**: as 14 ocorrências reais
 * são `.chip` (avatares 1, config 3, custos 4, robo 3, produções 1). O P2 e o
 * P3 chegaram nisso por caminhos independentes — o P2 chegou a trocar o JS para
 * emitir `.pill` e voltou atrás; o P3 pintou `.chip`. Os dois convergiram no
 * mesmo lugar, que é a regra da casa: **reusar o nome que já está em produção**.
 *
 * O resultado provisório foi pior que qualquer um dos dois: os MESMOS valores
 * declarados em dois blocos diferentes deste arquivo. Valor duplicado não fica
 * duplicado — ele diverge, e aí quem vier depois ganha por ordem de linha, que
 * é uma forma de decidir pintura que ninguém consegue ler. Está unificado aqui,
 * numa regra só, com os dois nomes.
 *
 * `.pill` fica como apelido e não como órfão: se alguma marcação nova nascer
 * copiando o mockup, ela pinta certo em vez de sair sem estilo nenhum.
 *
 * OS DOIS VOCABULÁRIOS DE MODIFICADOR entram juntos, porque produção não usa os
 * nomes do mockup: `.espera` é o `warn` dela e `.mau` é o `bad`. Traduzir a
 * marcação seria mexer no JS de cinco arquivos para trocar uma palavra.
 *
 * O ponto (`.pt`) FICA: ele não existe no mockup, não atrapalha o retângulo, e
 * é o que distingue os estados para quem não separa cor. */
.robo-raiz .pill, .robo-raiz .chip {
  display: inline-flex; align-items: center; gap: 5px;
  font-family: var(--mono); font-size: 10px; letter-spacing: .1em;
  text-transform: uppercase; border-radius: 3px; padding: 2px 7px;
  border: 1px solid var(--line); color: var(--faint); background: var(--surf2);
}
.robo-raiz .pill.ok, .robo-raiz .chip.ok {
  color: var(--ok); border-color: #1d4d2a; background: var(--ok-soft);
}
.robo-raiz .pill.warn, .robo-raiz .chip.espera {
  color: var(--warn); border-color: #4d3d12; background: var(--warn-soft);
}
.robo-raiz .pill.bad, .robo-raiz .chip.mau {
  color: var(--bad); border-color: #5c2226; background: var(--bad-soft);
}
.robo-raiz .pill.mute { color: var(--faint); border-color: var(--line); background: var(--surf2); }

/* `.note` (105-115) — NOVO. É o aviso COM MOTIVO. A casa tem `.aviso`, que é
   uma barra à esquerda; o mockup pede caixa inteira com ícone mono. Como
   `aviso()` do `shell.js` é usado em toda a tela do Robô, `.aviso` recebe aqui
   a pintura do `.note` — reusar o nome que já está em produção, como manda o
   mapa, em vez de criar um nome paralelo que ninguém emite. */
.robo-raiz .note,
.robo-raiz .aviso {
  display: flex; gap: 11px; align-items: flex-start;
  border-radius: var(--r); padding: 11px 13px; font-size: 13px;
  border: 1px solid var(--line); border-left: 1px solid var(--line);
  background: var(--surf2); color: var(--ink); margin-bottom: 18px;
}
.robo-raiz .note b, .robo-raiz .aviso b { font-weight: 620; color: var(--ink); }
.robo-raiz .note.ok, .robo-raiz .aviso.ok { background: var(--ok-soft); border-color: #1d4d2a; }
.robo-raiz .note.warn, .robo-raiz .aviso.espera { background: var(--warn-soft); border-color: #4d3d12; }
.robo-raiz .note.bad, .robo-raiz .aviso.erro { background: var(--bad-soft); border-color: #5c2226; }
.robo-raiz .note .ic { font-family: var(--mono); font-size: 12px; flex: none; padding-top: 1px; }
.robo-raiz .note.ok .ic { color: var(--ok); }
.robo-raiz .note.warn .ic { color: var(--warn); }
.robo-raiz .note.bad .ic { color: var(--bad); }

/* h2 / .sub (62-63) */
/* O TITULO DA PRODUCAO SELECIONADA NAO E UM SUBTITULO DE SECAO.
   Esta regra generica e `.pw-detail-title-row :is(h1, h2)` do
   production-workspace.css tem a MESMA especificidade (0,1,1) — e este arquivo
   carrega DEPOIS (index.html: production-workspace, depois robo_telas), entao
   o desempate por ordem dava a vitoria ao generico. Medido no app: o nome da
   producao aberta saia com 17px onde o simulador tem 30px (clamp 23-30).
   No simulador o defeito nao existe porque la nao ha o embrulho `.robo-raiz`.
   O `:not()` tira do generico SO o titulo da bancada; todo o resto do Robo
   (cabecalhos de painel, secoes, cartoes) continua em 17px. Preferido a
   reescrever o clamp aqui: duas copias do mesmo valor em dois arquivos e o
   defeito que este repo ja pagou para aprender. */
.robo-raiz h2:not(.pw-detail-title-row *) { font-size: 17px; font-weight: 640; margin: 0 0 4px; letter-spacing: -.01em; }
.robo-raiz .sub { color: var(--dim); font-size: 13px; margin: 0 0 22px; }
.robo-raiz .cabeca h1 { font-family: var(--sans); font-size: 19px; font-weight: 650; letter-spacing: -.01em; }
.robo-raiz .cabeca .sub { margin: 3px 0 0; font-size: 13px; }

/* ------------------------------------------------------------ tiles -- */
/* `.tiles`/`.tile` (144-153). ATENÇÃO, R4: existem DUAS famílias de tile em
   produção, e o mapa do prompt só citava uma. Abri as duas:
     `.tiles .tile .rot .val .pe`      estilo.css:841-845  (topo da tela do Robô)
     `.rb-tiles .rb-tile .rb-rot .rb-val`  aqui em cima     (tela de Custos)
   As duas recebem a mesma pintura — repintar só a que o mapa citava deixaria
   metade da tela com a paleta velha.

   `repeat(4,1fr)` e não `auto-fill`: o mockup crava quatro colunas, e a linha
   do topo do Robô tem exatamente quatro tiles. */
.robo-raiz .tiles, .robo-raiz .rb-tiles {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px;
  margin-bottom: 24px;
}
@media (max-width: 900px) {
  .robo-raiz .tiles, .robo-raiz .rb-tiles { grid-template-columns: repeat(2, 1fr); }
}
.robo-raiz .tile, .robo-raiz .rb-tile {
  background: var(--surf); border: 1px solid var(--line); border-radius: 8px;
  padding: 14px 16px; display: block;
}
.robo-raiz .tile .rot, .robo-raiz .rb-tile .rb-rot {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--dim); margin-bottom: 6px;
}
.robo-raiz .tile .val, .robo-raiz .rb-tile .rb-val {
  font-family: var(--sans); font-size: 24px; font-weight: 600;
  letter-spacing: -.02em; font-variant-numeric: tabular-nums; line-height: 1.2;
}
/* R9 — TIRAR O NÚMERO ERRADO NÃO PODE TIRAR A UNIDADE VERDADEIRA JUNTO. O
   `sem base` é estado de primeira classe e continua legível e MENOR que um
   número, para não se ler como valor. A pintura muda; o estado fica. */
.robo-raiz .tile .val.sembase, .robo-raiz .rb-tile .rb-val.sembase {
  color: var(--faint); font-size: 18px;
}
.robo-raiz .tile .pe, .robo-raiz .rb-tile .rb-un {
  color: var(--faint); font-size: 12px; margin-top: 3px;
}

/* ------------------------------------------- a barra em duas famílias -- */
/* `.nav`/`.navnote` (40-59) -> `.rb-abas`/`.rb-abas-nota`, os nomes que já estão
   em produção. O separador (`.rb-abas-sep`) já existe como elemento de verdade;
   ele recebe a pintura do `.nav .sep`. */
.robo-raiz .rb-abas {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  margin-bottom: 8px;
}
.robo-raiz .rb-abas-sep {
  width: 1px; align-self: stretch; background: var(--line); margin: 2px 12px;
  border: 0; padding: 0;
}
.robo-raiz .rb-abas .pchip {
  font-family: var(--mono); font-size: 11.5px; letter-spacing: .06em;
  text-transform: uppercase; color: var(--dim);
  background: transparent; border: 1px solid transparent; border-radius: var(--r);
  padding: 7px 11px; cursor: pointer;
  transition: color .12s, background .12s;
}
.robo-raiz .rb-abas .pchip:hover { color: var(--ink); background: var(--surf2); }
.robo-raiz .rb-abas .pchip.on {
  color: var(--ink); background: var(--surf3); border-color: var(--line);
}
/* `.nav button.on.work` do mockup: o sublinhado vermelho marca a família "o que
   você FAZ". Em produção a família se distingue por `.sai` (as de configurar),
   então a marca vai nas que NÃO são `.sai` — mesma afirmação, com o nome que já
   existe. */
.robo-raiz .rb-abas .pchip.on:not(.sai) { box-shadow: inset 0 -2px 0 var(--red); }
.robo-raiz .rb-abas .pchip.sai { color: var(--faint); }
.robo-raiz .rb-abas .pchip:focus-visible { outline: 2px solid var(--red); outline-offset: 1px; }
.robo-raiz .rb-abas-nota {
  font-family: var(--mono); font-size: 10px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--faint); margin: 0 0 24px;
}

/* ------------------------------------------------ a tela de produzir -- */
/* O formulário do pedido usa `.campo-ajuste` (já repintado acima) e as escolhas
   em cartão. `.picks`/`.pick` do mockup (117-129) -> `.rb-cartoes`/`.rb-cartao`,
   que é o que `robo.js` emite, e `.opcoes-cartao`/`.opcao-cartao`, que é o que
   `config.js` emite. Os dois nomes existem e os dois são repintados; inventar um
   terceiro seria o nome paralelo que o §2 proíbe. */
.robo-raiz .rb-cartoes, .robo-raiz .opcoes-cartao {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px;
}
@media (max-width: 820px) {
  .robo-raiz .rb-cartoes, .robo-raiz .opcoes-cartao { grid-template-columns: 1fr; }
}
.robo-raiz .rb-cartao, .robo-raiz .opcao-cartao {
  text-align: left; background: var(--surf); border: 1px solid var(--line);
  border-radius: var(--r); padding: 12px 13px; cursor: pointer; color: var(--ink);
  font-family: inherit; width: 100%;
}
.robo-raiz .rb-cartao.on,
.robo-raiz .opcao-cartao:has(input:checked) {
  border-color: var(--red); background: #180d0f;
}
.robo-raiz .rb-cartao.travado, .robo-raiz .opcao-cartao.desativada {
  opacity: .55; cursor: not-allowed;
}
/* R4 DE NOVO: `.rb-cartao` NÃO usa `b`/`small` — usa `.t` e `.d`
   (estilo.css:1950-1951), que por acaso são os MESMOS nomes do `.pick` do
   mockup. Quem usa `b`/`small` é o `.opcao-cartao` do `config.js`. Os dois
   entram; pintar só um deixaria uma das telas com a tipografia velha. */
.robo-raiz .rb-cartao .t, .robo-raiz .opcao-cartao b {
  font-weight: 580; font-size: 13.5px; display: block; margin-bottom: 2px;
  line-height: 1.25;
}
.robo-raiz .rb-cartao .d, .robo-raiz .opcao-cartao small {
  color: var(--dim); font-size: 12px; display: block; line-height: 1.35;
}
/* O MOTIVO DA OPÇÃO TRAVADA. No mockup é `.pick .why` em `--warn`; em produção
   o motivo é escrito DENTRO do `.d` do cartão travado (estilo.css:1961) e no
   `.motivo` do `.opcao-cartao`. Os dois já apontam para o amarelo da casa, que
   o remapeamento do topo já trocou por `--warn` — mas o TAMANHO é do mockup. */
.robo-raiz .rb-cartao.travado .d, .robo-raiz .opcao-cartao .motivo {
  color: var(--warn); font-size: 11.5px; margin-top: 5px;
}
/* O ESCOLHIDO ERA VERDE, E VIRA VERMELHO. A regra antiga (estilo.css:1955-1957)
   escolheu verde com um argumento bom: *"duas cores para 'isto está
   selecionado' na mesma página é o aluno aprendendo o produto duas vezes"* — e
   o vizinho dela era o `.pchip.on`. O argumento continua de pé e a conclusão
   muda junto: no mockup as DUAS coisas são vermelhas (`.pick.on` borda `--red`
   + fundo `#180d0f`; `.nav button.on.work` com sublinhado `--red`). Continua
   sendo uma cor só para "selecionado" — a do mockup. Sem esta linha o título
   do cartão escolhido ficaria verde dentro de uma caixa vermelha. */
.robo-raiz .rb-cartao.on .t { color: var(--ink); }
.robo-raiz .rb-cartao:hover:not(:disabled),
.robo-raiz .opcao-cartao:hover { border-color: var(--line); background: var(--surf2); }
.robo-raiz .rb-cartao.on:hover { background: #180d0f; }
.robo-raiz .rb-cartao:focus-visible, .robo-raiz .opcao-cartao:focus-within {
  outline: 2px solid var(--red); outline-offset: 1px;
}

/* ------------------------------------- o resto do formulário do pedido -- */
/* `.rb-linha2` é o `.row.two` do mockup com outro nome (grid 1fr 1fr): o gap
   sobe de 12 para 18 e ele passa a colapsar em 820px, que é o que o mockup faz
   e produção não fazia. */
.robo-raiz .rb-linha2, .robo-raiz .rb-par { gap: 18px; }
@media (max-width: 820px) {
  .robo-raiz .rb-linha2, .robo-raiz .rb-par { grid-template-columns: 1fr; }
}
.robo-raiz .rb-produzir { gap: 18px; }

/* O `<details>` das opções avançadas recebe a TIPOGRAFIA do `.grp` do mockup
   (mono 10px, `.14em`, uppercase, `--dim`), mas CONTINUA sendo um `<details>`.
   No mockup o "Opções avançadas" é um separador estático; trocar o controle
   por um título fixo mudaria comportamento — proibido neste passo. Divergência
   nomeada, não deixada por conta. */
.robo-raiz .rb-avancadas > summary {
  font-family: var(--mono); font-size: 10px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--dim); font-weight: 500;
}
.robo-raiz .rb-avancadas { border-color: var(--line); background: var(--surf); }
.robo-raiz .rb-avancadas > .ajuda {
  text-transform: none; letter-spacing: 0; font-family: var(--sans);
  font-size: 12px; color: var(--faint);
}

/* A faixa do equilíbrio real/IA. `accent-color` já vem vermelho pelo
   remapeamento (`--azul` -> `--red`); o que falta é o número lido ao lado. */
.robo-raiz .rb-lido {
  font-family: var(--mono); font-size: 12px; color: var(--dim);
  font-variant-numeric: tabular-nums;
}

/* O roteiro. `.rb-escrever textarea` já existe no estilo.css com a borda da
   casa; aqui ele vira `.fld`. */
.robo-raiz .rb-escrever textarea {
  background: var(--surf); border: 1px solid var(--line); border-radius: var(--r);
  color: var(--ink); padding: 9px 11px; font-family: inherit; font-size: 14px;
}
.robo-raiz .rb-escrever textarea:focus-visible {
  outline: 2px solid var(--red); outline-offset: 1px; border-color: var(--line);
}

/* `prefers-reduced-motion` (linha 245 do mockup) vem junto. */
@media (prefers-reduced-motion: reduce) {
  .robo-raiz * { transition: none !important; animation: none !important; }
}

/* ══ P3 · A CONFIGURAÇÃO ══
   As quatro telas de configurar: Avatares, Canais, Ajustes e Custos.
   Fonte de TODO valor: research/conveyer-e-ytfill/robo-mockup.html, <style>
   linhas 82-215 (lidas, não lembradas) e as `<section>` `s-avatares` (562-598),
   `s-canais` (601-633), `s-ajustes` (636-708) e `s-custos` (711+).

   NADA AQUI REDECLARA TOKEN NEM PRIMITIVA — o P1 já fez as duas coisas. Isto é
   só o mapeamento `nome do mockup -> nome que JÁ EXISTE em produção`, e o mapa
   foi conferido abrindo cada seletor. TRÊS LINHAS DO MAPA DO ENUNCIADO ESTAVAM
   ERRADAS, e segui o código:

     mockup     enunciado dizia        o que existe de verdade
     .keys/.key .chaves-linhas/-linha  .chaves-grid / .chave-card  (estilo:873)
     .grp       "novo, sem nome"       .grupo-de-chaves (estilo:1871) e, no
                                       Custos, `.cabeca.custos-grupo`
     .abre      "veja o que emite"     .abrir-chave (estilo:1891)

   `.chaves-linhas`/`.chave-linha` existem, mas são outra coisa: a LISTA de
   chaves já guardadas DENTRO de um cartão (robo_telas.css:110-115). Pintar
   aquilo como se fosse o cartão deixaria a grade inteira sem pintura. */

/* ---------------------------------------------- o estado de uma linha -- */
/* `.pill` (94-103) -> `.chip` SUBIU PARA O BLOCO P1, junto do `.pill`, numa
   regra só com os dois nomes.
   O P3 e o P2 acertaram o NOME (produção emite `.chip`, ninguém emite `.pill`)
   e cada um declarou os valores no seu bloco. Dois blocos com o mesmo valor não
   ficam iguais: divergem, e aí quem ganha é a ordem das linhas — que não é uma
   forma legível de decidir pintura. Unificado na primitiva, que é onde o estado
   de linha pertence. Ver o comentário lá para o porquê dos dois vocabulários de
   modificador (`.espera` = warn, `.mau` = bad). */

/* ------------------------------------------------------------ AVATARES -- */
/* `.avlist` (205-206) -> `.cartoes`. Quatro colunas cravadas, e não o
   `auto-fill` de antes: é o que o mockup pede, e num monitor de 1240px o
   `minmax(230px,1fr)` abria CINCO colunas — cartão de retrato quadrado fica
   pequeno demais nessa largura. O colapso é em 820px, para 2 colunas. */
.robo-raiz .cartoes {
  grid-template-columns: repeat(4, 1fr); gap: 12px; margin-top: 16px;
}
@media (max-width: 820px) {
  .robo-raiz .cartoes { grid-template-columns: repeat(2, 1fr); }
}
/* `.av` (207): o raio sobe de `--r` (6) para 8 — o mockup usa 6 em campo e
   botão e 8 em cartão, tile e chave, e o `.cartao-avatar` é cartão. */
.robo-raiz .cartao-avatar { background: var(--surf); border-color: var(--line); border-radius: 8px; }
/* `.av .ph` (208-212) -> `.foto-do-avatar`, e SÓ na versão `div`.
   `div.` de propósito: quando o avatar tem miniatura o mesmo nome é um `<img>`,
   e `display:grid` + `place-items` num elemento substituído não faz nada de
   útil enquanto `object-fit:cover` (robo_telas.css:144) faz — sobrescrever a
   caixa dele seria trocar uma regra que funciona por uma que não se aplica. */
.robo-raiz .cartao-avatar div.foto-do-avatar {
  background: linear-gradient(150deg, #232329, #16161a);
  display: grid; place-items: center; color: var(--faint);
  font-family: var(--mono); letter-spacing: .1em;
}
/* `.av .n` (214) -> `.rb-nome`; `.av .m` (215) -> `.peq4`, que é o que o cartão
   emite para o id da HeyGen. O `margin-top:3px` do mockup já sai do `gap: 6px`
   do `.corpo`. */
.robo-raiz .cartao-avatar .rb-nome { font-weight: 580; font-size: 13.5px; }
.robo-raiz .peq4 { font-size: 10.5px; color: var(--faint); }

/* -------------------------------------------------------------- CANAIS -- */
/* A linha de um canal é o `.card` de baixo do `s-canais` (629-632): mesma
   caixa, mesmo raio, e o `Editar` empurrado para a direita — o que produção já
   faz com `margin-left:auto`. Só a caixa muda. */
.robo-raiz .linha-canal {
  background: var(--surf); border-color: var(--line); border-radius: 8px;
  padding: 18px;
}

/* ------------------------------------------------------------- AJUSTES -- */
/* `.grp` (197-203) -> `.grupo-de-chaves`. Depois do remapeamento do P1 quase
   tudo já batia (`--texto2`->`--dim`, `--linha`->`--line`, e o `.porque` já era
   sans 12px `--faint` sem versalete); sobraram DOIS números: 11px -> 10px e a
   margem de cima 24 -> 26. */
.robo-raiz .grupo-de-chaves { font-size: 10px; margin: 26px 0 12px; }

/* `.keys` (179-180) -> `.chaves-grid`. Três colunas cravadas e 1 em 900px.
   Aqui a quantidade é do SERVIDOR (`d.chaves`), então `auto-fill` seria
   defensável — mas os dois grupos têm três cartões cada nos payloads reais, e
   o mockup crava três. Quantidade diferente só empilha. */
.robo-raiz .chaves-grid { grid-template-columns: repeat(3, 1fr); gap: 12px; }
@media (max-width: 900px) {
  .robo-raiz .chaves-grid { grid-template-columns: 1fr; }
}
/* `.key` (181) -> `.chave-card`: raio 8, e o padding 15 já era o do mockup. */
.robo-raiz .chave-card { border-radius: 8px; }
/* AS TARJAS DE 3px DA ESQUERDA SAEM, E ISSO NÃO PERDE ESTADO. O mockup só tem
   uma variante de cartão (`.key.miss`, borda inteira `#4d3d12`) e carrega o
   resto num selo dentro do título. Em produção o selo existe e é melhor: cada
   chave guardada mostra `testada`/`recusada`/`guardada` na própria linha
   (config.js:322-324), e a obrigatória sem chave mostra o aviso do topo COM O
   MOTIVO. O que sai é a redundância, não o sinal. */
.robo-raiz .chave-card.ok,
.robo-raiz .chave-card.vazia,
.robo-raiz .chave-card.ruim { border-left: 1px solid var(--line); }
.robo-raiz .chave-card.falta { border: 1px solid #4d3d12; }
/* `.key h3` (183) -> `.ch-nome`: 18px/`.02em` da casa vira 14px/600 sem
   espacejamento, e o alinhamento vai de `baseline` para `center` porque agora
   há um selo do lado. */
.robo-raiz .chave-card .ch-nome {
  font-size: 14px; font-weight: 600; letter-spacing: 0; align-items: center; gap: 8px;
}
/* `.key p` (184): a descrição do papel da chave. `min-height:34px` é o que
   alinha o rodapé dos três cartões da linha quando um texto tem duas linhas e
   o outro tem uma. O seletor pega SÓ ela (a que vem logo depois do topo) — o
   texto do pool, mais abaixo, continua `--faint` 12px. O `margin:0` porque a
   separação já vem do `gap: 10px` da coluna flex do cartão. */
.robo-raiz .chave-card > .ch-topo + .dica {
  color: var(--dim); font-size: 12.5px; min-height: 34px; margin: 0;
}
/* `.key .src` (185) já saiu no `.peq4` acima. O campo da chave vira a caixa do
   `.fld` (surf / line / raio 6 / 9px 11px) — mas SEGUE MONO. O mockup usa
   `.fld` puro ali (sans 14px) e mostra `sk-or-••••••••••4a2f`; uma chave
   mascarada em fonte proporcional embaralha os pontos e o sufixo, que é
   justamente o pedaço que se confere. Divergência nomeada. */
.robo-raiz .chave-card input {
  background: var(--surf); border: 1px solid var(--line); border-radius: var(--r);
  padding: 9px 11px; font-size: 12.5px;
}
.robo-raiz .chave-linha { background: var(--surf2); border-radius: var(--r); }
/* `.abre` (186-196) -> `.abrir-chave`. `align-self`, `flex-wrap` e `max-width`
   NÃO saem: eles consertam a quebra do rótulo no meio ("Pegar a / chave") que
   já foi vista no cartão do Groq, e o mockup não tem cartão estreito para ter
   descoberto isso. O que muda é a pintura. */
.robo-raiz .abrir-chave {
  gap: 6px; margin-top: 10px; font-size: 10.5px; letter-spacing: .06em;
  color: var(--ink); background: var(--surf2); border: 1px solid var(--line);
  border-radius: var(--r); padding: 6px 10px;
}
.robo-raiz .abrir-chave:hover { border-color: var(--red); background: var(--surf3); }
.robo-raiz .abrir-chave:focus-visible { outline: 2px solid var(--red); outline-offset: 1px; }
.robo-raiz .abrir-chave .caminho { color: var(--faint); }
.robo-raiz .abrir-chave .seta { color: var(--red); font-size: 11px; }
/* O bloco da HeyGen é o `.card` do grupo "Avatar" (699-707): caixa de cartão,
   sem a tarja verde à esquerda — o estado já está no selo `ok` ao lado do
   título, e duas afirmações do mesmo fato numa linha só é ruído. */
.robo-raiz .conexao-heygen {
  border: 1px solid var(--line); border-radius: 8px; padding: 18px; gap: 16px;
}

/* -------------------------------------------------------------- CUSTOS -- */
/* O `.dica` do P1 ganhou `margin: 6px 0 0`, e isso ATROPELOU cinco regras que
   zeram essa margem de propósito: elas são `.x .dica` (0,2,0), empatam com
   `.robo-raiz .dica` (0,2,0) e perdem na ordem de carregamento. O efeito é
   pequeno e feio: em toda linha que alinha um selo, um número e uma frase pela
   BASE, a frase desce 6px sozinha. Restaurado com (0,3,0), que é o mínimo para
   ganhar — não com `!important`, que só empurraria o problema para o próximo. */
.robo-raiz .custos-periodo-topo .dica,
.robo-raiz .custos-pilhas .dica,
.robo-raiz .custos-plano .dica,
.robo-raiz .custos-plano-topo .dica,
.robo-raiz .custos-filtros .dica { margin: 0; }
.robo-raiz .conexao-heygen .dica { margin: 3px 0 0; }
/* Mesma causa, e este é o do mockup (linha 743: `margin:-10px 0 20px`): a
   frase do custo efetivo cola nos tiles porque ela é a LEITURA deles. */
.robo-raiz .custos-efetivo { margin: -10px 0 20px; }

/* OS TILES DO CUSTOS SÃO TRÊS, E A GRADE ERA DE QUATRO. O P1 pôs
   `.tiles, .rb-tiles` em `repeat(4,1fr)` porque a linha do topo do Robô tem
   quatro tiles — mas `.rb-tiles` é emitido em UM lugar só, `custos.js:385`, e
   ali são exatamente três (`Planos / mês`, `Cobrado por uso`, `Total do
   período`). Com quatro colunas a quarta ficava vazia. O mockup sabe disso: a
   linha 737 escreve `style="grid-template-columns:repeat(3,1fr)"` na mão.
   A média de 900px é REDECLARADA porque a do P1 empata em especificidade e
   vem ANTES — sem repetir, o telefone voltaria para três colunas. */
.robo-raiz .rb-tiles { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 900px) {
  .robo-raiz .rb-tiles { grid-template-columns: repeat(2, 1fr); }
}
/* `.tile .un` (153) -> a terceira linha do tile é um `.dica`, e NÃO o `.rb-un`
   que o P1 mirou: `custos.js:120` emite `h('div', {class:'dica'}, motivo)`.
   Nenhum nó tem `.rb-un` no repositório — aquela metade da regra do P1 não
   casa com nada. Aqui o que falta é só a distância: 3px, não 6. */
.robo-raiz .rb-tile .dica { margin-top: 3px; color: var(--faint); font-size: 12px; }

/* O cartão do período (715): `.card` com `padding:14px 16px`. */
.robo-raiz .custos-periodo {
  background: var(--surf); border-color: var(--line); border-radius: 8px;
  padding: 14px 16px; margin-bottom: 16px;
}
/* `.lab` (64-68) -> `.custos-rot`, que é o rótulo de "Período atual" e das três
   famílias de cobrança. Mesmo papel, nome próprio (ele nasceu assim para não
   colidir com o `.rb-rot` dos tiles). */
.robo-raiz .custos-rot { font-size: 10.5px; letter-spacing: .13em; color: var(--dim); }

/* `.grp` (197-203) -> `.custos-grupo`, os quatro separadores da tela. Em
   produção ele é um `.cabeca` com `<h1>`, ou seja um TÍTULO de 19px; no mockup
   os quatro são separadores de versalete com régua em cima. Fica como no
   mockup — e por isso o `style="font-size:19px"` saiu do `custosGrupo` em
   `custos.js`: estilo em linha ganha de folha, então mantê-lo obrigaria a um
   `!important` para desfazer o que o próprio arquivo escreve.
   O QUE FICA DIFERENTE: no mockup a nota do grupo é irmã do título, na mesma
   linha (`.grp .c`); aqui ela é `.sub` dentro do mesmo bloco e cai na linha de
   baixo. Trocar isso é mexer na marcação além do combinado. */
.robo-raiz .custos-grupo {
  border-top: 1px solid var(--line); padding-top: 14px; margin: 26px 0 12px;
  align-items: center; gap: 10px;
}
.robo-raiz .custos-grupo h1 {
  font-family: var(--mono); font-size: 10px; font-weight: 500;
  letter-spacing: .14em; text-transform: uppercase; color: var(--dim);
}
.robo-raiz .custos-grupo .sub {
  font-family: var(--sans); font-size: 12px; letter-spacing: 0;
  text-transform: none; color: var(--faint); margin: 2px 0 0;
}

/* Os planos: `.row.two` (78) — duas colunas de 18px que colapsam em 820px.
   `auto-fill` com mínimo de 320px abriria TRÊS colunas em 1240px para os dois
   cartões que existem, e a terceira ficaria vazia; aqui a quantidade não é
   livre, é o número de provedores que consomem plano. */
.robo-raiz .custos-planos { grid-template-columns: 1fr 1fr; gap: 18px; }
@media (max-width: 820px) {
  .robo-raiz .custos-planos { grid-template-columns: 1fr; }
}
.robo-raiz .custos-plano {
  background: var(--surf); border-color: var(--line); border-radius: 8px; padding: 18px;
}
/* `s-custos` 758: o cartão do plano que falta informar leva a borda inteira em
   `#4d3d12`, igual ao `.key.miss`. É a mesma afirmação ("falta você me contar
   isto") e passa a ter a mesma cara nas duas telas. */
.robo-raiz .custos-plano.falta { border-color: #4d3d12; }
/* APAGADA: `.robo-raiz .custos-filtros { gap: 18px }` vivia aqui e era LETRA
   MORTA — o bloco da FRENTE D declara `gap: 10px` mais abaixo no mesmo arquivo,
   com a mesma especificidade, e quem vem depois ganha. O 18 saiu de ler o `.row`
   do mockup em vez do `style` da linha de cima; o 10 é o valor certo (mockup
   770). Quem escreveu não podia apagar esta linha — era bloco alheio, e essa
   regra existe para as frentes não se sobrescreverem em silêncio. */

/* A TABELA (132-142). Eu ia deixá-la de fora por causa do aviso de que o P2
   também mexeria em `.tabela` — fui CONFERIR em vez de supor, e o bloco P2 já
   está fechado com 24 seletores, nenhum deles `.tabela`: as telas dele usam
   `.rp-tab`. Medido: `class: 'tabela'` aparece em DOIS lugares no repositório,
   `custos.js:338` e `custos.js:516`, os dois nesta tela. Ela é minha, e sem
   isto seria a única superfície grande do Custos com a tipografia velha.

   `border-bottom` explícito, NUNCA o atalho `border`: `.custos-tabela
   th.custos-corte` (estilo.css:2043) desenha a régua VERTICAL que separa os
   três blocos da tabela (uso · plano · estimativa), empata em especificidade
   com o seletor daqui e perderia na ordem. Foi somar plano com uso na mesma
   coluna que já inflou cada vídeo em 4x — a régua é load-bearing.

   `white-space: nowrap` e `tr:hover` FICAM: a tabela tem até 15 colunas e rola
   dentro do `.rb-rolagem` (o `.scroll` do mockup); o mockup nunca teve uma
   tabela desse tamanho para ter descoberto que precisava dos dois. */
.robo-raiz .tabela { font-size: 13px; }
.robo-raiz .tabela th {
  font-family: var(--mono); font-size: 10px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--dim); text-align: left;
  font-weight: 500; padding: 0 12px 8px; border-bottom: 1px solid var(--line);
}
.robo-raiz .tabela td {
  padding: 11px 12px; border-bottom: 1px solid var(--line-soft);
  vertical-align: middle;
}
.robo-raiz .tabela td.num { text-align: right; font-variant-numeric: tabular-nums; }
.robo-raiz .tabela th.num { text-align: right; }
.robo-raiz .tabela tr:last-child td { border-bottom: 0; }
.robo-raiz .tabela tr:hover td { background: var(--surf2); }

/* O que é EXCLUSIVO do Custos (`.custos-corte`, `.custos-plano-col`,
   `.custos-vazio`) não precisa de linha nenhuma: eles já leem
   `--linha2`/`--amarelo`/`--texto3`, que o remapeamento do P1 trocou por
   `--line`/`--warn`/`--faint` sozinho. */

/* ══ fim do P3 ══ */


/* ══ P2 · O ACOMPANHAMENTO ══
   As telas **Acompanhar** (a aba do `robo.js` e o detalhe `/robo-producao/<id>`
   do `robo_producoes.js`) e **Produções**.

   Fonte: `research/conveyer-e-ytfill/robo-mockup.html`. A linha do `<style>`
   está citada em cada bloco, e cada número foi LIDO de lá — nenhum foi
   lembrado nem arredondado.

   Este bloco não declara token nenhum e não reescreve primitiva: os tokens e as
   primitivas (`.lab .fld .hint .row .card .btn .pill .note`, os tiles, a barra
   e a tela Produzir) são do P1, acima. Aqui só entra o que é destas duas telas.

   TODO seletor começa em `.robo-raiz` — é ele que carrega a paleta, e uma regra
   que escapasse dele repintaria login, checkout e aulas, que o mockup não
   descreve.
   ══════════════════════════════════════════════════════════════════════════ */

/* ------------------------------------------------------ a régua de fases -- */
/* mockup 156-165 (`.fases` `.fase` `.fase.done` `.fase.now` `.fasenames`
   `span.now`) -> `.rb-fases` `.rb-fase` `.rb-fase.feito` `.rb-fase.agora`
   `.rb-fasenames` `.rb-fasenome`, que é o que `reguaDeFases()` emite
   (`robo.js:222-243`) e o que o `estilo.css:1732-1760` já pinta.
   Os dois chamadores dela são meus: a aba Acompanhar e o detalhe.

   O QUE JÁ BATIA e por isso não está aqui: `display:flex`, `gap:3px`,
   `height:5px`, `border-radius:2px`, `flex:1` por segmento, a família mono, o
   versalete, `.feito -> var(--ok)` e `.agora -> var(--red)` (esta última porque
   o P1 remapeia `--azul` para `--red`). O espaço de 6px entre a barra e os
   nomes também já bate: o mockup o põe como `margin-bottom` da barra e a
   produção como `margin-top` dos nomes — mesma distância computada, e mexer
   nisso seria trocar um valor certo por outro igual.

   O QUE ESTAVA VINDO DO TOKEN ERRADO — três, e são os três casos em que o nome
   da casa e o do mockup discordam:
     trilho vazio   `--linha` (=`--line`, #2a2a30)  ->  `--surf3` (#232329)
     nome corrente  `--azul`  (=`--red`)            ->  `--ink`
     nome cumprido  `--texto2`(=`--dim`)            ->  herda `--faint`
   O último é escolha do mockup e vale a pena dizer por quê: quem já passou é
   dito pela BARRA verde acima, e repetir a ênfase no nome gasta o contraste que
   só o segmento de AGORA deveria ter. */
/* A RÉGUA ESTAVA LISA — os seis segmentos no mesmo cinza, o run inteiro.
   Medido no navegador: `feito`, `agora` e vazio todos em `rgb(35,35,41)`.

   As classes sempre estiveram certas; a cor é que não chegava. `estilo.css`
   pinta `.rb-fase.feito` e `.rb-fase.agora` com especificidade (0,2,0), e a
   linha abaixo — `.robo-raiz .rb-fase` — tem a MESMA (0,2,0). Empate resolve
   por ordem, e esta folha é injetada depois (`config.js`), então ela vencia os
   dois estados e apagava a régua inteira. O trilho vazio era a única coisa que
   se via, e por isso ninguém percebeu que faltava algo: a barra parecia
   completa, só não dizia nada.

   Os dois estados voltam AQUI DENTRO, com um seletor que não empata. */
.robo-raiz .rb-fase { background: var(--surf3); }
/* CUMPRIDA: branco apagado. Ela não precisa competir — quem já passou é
   história, e gastar contraste nela tira do único segmento que importa. */
.robo-raiz .rb-fase.feito { background: #4d4d57; }
/* AGORA: branco cheio, e NÃO vermelho.
   O `--azul` que o `estilo.css` usa aqui está remapeado para `--red` dentro do
   `.robo-raiz`, então a intenção original era um segmento vermelho. Isso valia
   antes do placar existir; agora vermelho SIGNIFICA filmagem real, e pintar o
   cromo com ele faria o olho procurar procedência numa barra que só diz em que
   etapa o robô está. É a mesma regra que já mantém a barra de cobertura branca
   em vez de vermelha. */
.robo-raiz .rb-fase.agora { background: var(--ink); }
.robo-raiz .rb-fasenames {
  font-size: 9.5px; letter-spacing: .08em; margin-bottom: 20px;
}
/* MEDIDO sobre o `--ground` (#0b0b0d), que e' onde a regua vive: `--faint`
   da' 3,11:1 num rotulo de 9,5px, e o piso para texto pequeno e' 4,5. `--dim`
   da' 6,05. A intencao — "quem ja' passou nao compete com o AGORA" — continua
   valendo e sai do PESO e do branco cheio do segmento corrente, nao de deixar
   a palavra ilegivel. */
.robo-raiz .rb-fasenome.feito { color: var(--dim); }
.robo-raiz .rb-fasenome.agora { color: var(--ink); }

/* O CONSERTO DE CELULAR DO `estilo.css` É MEDIDO E CONTINUA VALENDO — mas ele
   mora em `@media(max-width:640px){.rb-fasenames{…}}`, com especificidade (0,1,0)
   contra os (0,2,0) da regra logo acima. Sem repeti-lo aqui, a pintura nova
   desligaria em silêncio um conserto que ninguém pediu para desligar: a 390 px
   a coluna dá 45 px e "narração"/"montagem" — as duas PONTAS da régua — voltam
   a sair como reticências. É a armadilha de sempre: regra mais específica
   escrita depois não "some" no celular, ela ganha lá também. */
@media (max-width: 640px) {
  .robo-raiz .rb-fasenames { font-size: 9px; letter-spacing: 0; text-transform: none; }
  .robo-raiz .rb-fasenum { display: none; }
  .robo-raiz .rb-fasenome.agora { flex: 1 1 0; overflow: hidden; }
}

/* ------------------------------------------------------------------ log -- */
/* mockup 166-176 (`.log`, `.log div`, `.log .t/.f/.m`) -> DOIS logs em
   produção, e os dois recebem a mesma pintura:

     `.rb-log`/`.rb-linha`/`.rb-hora`/`.rb-fase-col`/`.rb-texto`
        estilo.css:1704-1712 e :1777  — a aba Acompanhar (`robo.js`)
     `.rp-log`/`.rp-hora`/`.rp-fase`
        folha embutida do `robo_producoes.js` — o detalhe da produção

   Pintar um só deixaria a MESMA informação com duas caras conforme o caminho
   por onde o aluno chegou nela — e os dois caminhos existem de propósito (a aba
   para o que está rodando, o detalhe para qualquer vídeo antigo).

   `#08080a` é literal do mockup e NÃO é `--ground` (#0b0b0d): o log é um degrau
   mais fundo que a página, e é isso que o separa do resto sem gastar uma
   segunda borda. Os dois logs vinham de `--void`, que o P1 mapeia para
   `--ground` — quase igual, e "quase" aqui apaga a separação.

   A COR DA MENSAGEM VAI NO CONTÊINER, E NÃO NO `.m`. No mockup `.log .m` é
   #c9c9cf. Aqui a mensagem é o único filho SEM cor própria (a hora e a fase têm
   as suas), então declará-la apagaria `n-aviso`/`n-erro`, que pintam a LINHA
   inteira e chegam à mensagem por herança. Posta no contêiner, a mensagem sai
   idêntica ao mockup e o nível continua mandando quando existe.

   NÃO EXISTE `n-ok` AQUI, e a ausência é medida: o mockup tem `.m.ok`, mas o
   agente só emite `nivel: "info"` — `fila.Registrador.log` tem o parâmetro
   `nivel` e nenhum chamador o usa (varrido em `instalador/_saida/carga/src/`).
   Escrever a regra seria pintar um estado que nada produz. */
.robo-raiz .rb-log, .robo-raiz .rp-log {
  background: #08080a; border: 1px solid var(--line); border-radius: var(--r);
  padding: 14px 16px; font-family: var(--mono); font-size: 12px;
  line-height: 1.85; max-height: 340px; overflow: auto; color: #c9c9cf;
}
.robo-raiz .rb-linha, .robo-raiz .rp-log > div { gap: 12px; }

/* A FAIXA DE FONTE NA LATERAL DA LINHA. Ela é o que deixa o log varrível sem
   ler: vermelho é o YouTube trabalhando, violeta é imagem de IA, azul é o
   apresentador. O cinza é todo o resto — e é o default, porque o agente inventa
   nome de fase e uma faixa colorida para fase desconhecida afirmaria uma
   procedência que ninguém apurou.

   `box-shadow: inset`, NUNCA `border-left`: a linha é flex e a coluna da fase
   tem `width` fixa logo abaixo — borda empurraria todas as colunas 2px e
   desalinharia o log inteiro, que existe justamente para ser lido em coluna. */
/* `> *` E NAO `> div`, e a diferenca e' um seletor de tipo.
   `.robo-raiz .rp-log > div` e' (0,2,1) por causa do `div`, e as tres regras
   de cor logo abaixo sao (0,2,0). Especificidade vence ordem, entao este ramo
   ganhava delas e a calha do log ficava CINZA para sempre -- mas so' na tela
   de UMA producao (`/robo-producao/<id>`), porque a aba Acompanhar usa
   `.rb-linha`, que empata em (0,2,0) e perde por ordem, como deve.
   A MESMA informacao com duas caras conforme o caminho por onde o aluno
   chegou nela. `*` tem especificidade zero e devolve o empate. */
.robo-raiz .rb-linha, .robo-raiz .rp-log > *, .robo-raiz .rb-agora {
  padding-left: 9px; box-shadow: inset 2px 0 0 var(--fonte-cromo); }
.robo-raiz .fonte-real   { box-shadow: inset 2px 0 0 var(--fonte-real); }
.robo-raiz .fonte-ia     { box-shadow: inset 2px 0 0 var(--fonte-ia); }
.robo-raiz .fonte-avatar { box-shadow: inset 2px 0 0 var(--fonte-avatar); }
/* `.f{color:var(--dim); width:88px}` (173). Os dois lados vinham de `--texto3`
   (=`--faint`), a mesma cor da hora — e a coluna do meio existe justamente para
   ser varrida de olho, o que exige que ela não se confunda com a da esquerda.
   `width` fixa (e não a `min-width:5.5rem` que o `.rp-fase` tinha): com
   `min-width`, uma fase de nome longo empurra a coluna e desalinha as linhas
   seguintes, que é o oposto do que a coluna serve. As reticências vêm do
   `.rb-fase-col`, que já resolvia isso do lado do `robo.js`. */
.robo-raiz .rb-fase-col, .robo-raiz .rp-log .rp-fase {
  color: var(--dim); flex: none; width: 88px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* A LINHA DE AGORA — a última do log, repetida FORA da rolagem.
   Quem sobe para reler uma linha antiga perde de vista o que está acontecendo
   neste segundo, e a tela volta a parecer parada. Aqui ela nunca some.

   Colada no pé do log, sem borda dupla no meio, para as duas lerem como uma
   peça só. O texto é `--ink` contra o `#c9c9cf` do histórico: é o brilho que
   diz "esta é a de agora", sem piscar nada — e piscar foi exatamente a queixa
   do dono sobre a tela anterior. */
.robo-raiz .rb-agora {
  display: flex; gap: 12px; align-items: baseline;
  padding: 9px 16px 9px 9px; margin-top: -1px;
  background: var(--ground); border: 1px solid var(--line);
  border-radius: 0 0 var(--r) var(--r);
  font-family: var(--mono); font-size: 12px; line-height: 1.6;
  /* SEM `box-shadow` AQUI. Ele existia e anulava a calha colorida: este bloco
     vem depois de `.fonte-real`/`.fonte-ia`/`.fonte-avatar`, mesma
     especificidade, então vencia por ordem e a linha de agora saía sempre
     cinza. O default agora vem do mesmo lugar dos outros, ANTES das cores. */
}
.robo-raiz .rb-agora .rb-texto { color: var(--ink); }
/* O log perde os cantos de baixo quando a linha de agora está colada nele.
   `:has` degrada sozinho em navegador que não o tem: o pior caso é um canto
   arredondado a mais, nunca informação perdida. */
.robo-raiz .rb-log:has(+ .rb-agora:not([hidden])) {
  border-radius: var(--r) var(--r) 0 0;
}
.robo-raiz .rb-agora[hidden] { display: none; }

/* ----------------------------------------- o cabeçalho de uma produção -- */
/* mockup 231-238 (`.runhead` `.k` `.v`) -> `.rp-cabecalho` `.rp-k` `.rp-v`
   (folha embutida do `robo_producoes.js`). `.rp-v` já bate byte a byte —
   0.8438rem são os 13.5px do mockup, e `tabular-nums` já está lá. */
.robo-raiz .rp-cabecalho {
  gap: 10px 18px; border-radius: 8px; padding: 13px 16px; margin-bottom: 18px;
}
.robo-raiz .rp-cabecalho .rp-k {
  font-size: 10px; letter-spacing: .12em; color: var(--dim); margin-right: 6px;
}

/* --------------------------------------------------------------- tabela -- */
/* mockup 131-142 e 220 (`table` `th` `td` `td.num` `th.num` `tr:last-child td`
   `td.acoes` `.scroll`) -> `.rp-tab` dentro de `.rolagem` (estilo.css:847).

   `.rolagem` e não `.rb-rolagem`: as três tabelas destas telas usam a primeira
   (`robo_producoes.js:419` a lista, `:572` as cenas, `robo.js:1471` o histórico
   simples de reserva). A `.rb-rolagem` é da tela de Custos e fica fora daqui.

   No mockup a moldura da tabela é do `.card{padding:0}` que envolve o
   `.scroll`; em produção ela já é do próprio `.rolagem` (borda, fundo `--sup` e
   raio). Mesmo desenho com uma caixa a menos — só o raio muda, de `--r` (6px)
   para os 8px que o mockup dá a cartão, tile e chave.

   `background:transparent` no `th` é obrigatório e não é enfeite: o
   `estilo.css:850` pinta TODO `th` da casa com `--sup2`, e o cabeçalho do
   mockup não tem faixa — ele se separa pela borda de baixo e pelo versalete.

   `border-bottom` do `td` sai de `--line-soft`, que é a divisória INTERNA e
   mais escura que a `--line` do cabeçalho: é a hierarquia que o mockup declara
   (136 contra 138) e que a produção não tinha, porque `--linha` servia aos dois.
   A regra `tr:last-child td{border-bottom:0}` da folha embutida continua
   ganhando desta (0,2,2 contra 0,2,1) — que é exatamente a linha 141. */
.robo-raiz .rolagem { border-radius: 8px; }
.robo-raiz .rp-tab th {
  font-size: 10px; letter-spacing: .12em; font-weight: 500;
  color: var(--dim); padding: 0 12px 8px; background: transparent;
}
.robo-raiz .rp-tab td {
  padding: 11px 12px; border-bottom: 1px solid var(--line-soft);
  vertical-align: middle;
}
.robo-raiz .rp-tab td.rp-fim { white-space: nowrap; }

/* ------------------------------------------------- a ação de uma linha -- */
/* mockup 221-229 (`.lnk`, `:hover`, `[disabled]`, `[disabled]:hover`,
   `:focus-visible`) -> `.rp-acao` / `.rp-acao:disabled`.

   O SUBLINHADO SAI. No mockup a cor vermelha mais o fundo no `hover` já dizem
   que aquilo clica; com quatro ações lado a lado numa célula (`abrir · mp4 ·
   retomar · apagar`), quatro sublinhados as fundem numa frase só.

   O `[disabled]` continua LEGÍVEL, apagado e sem cursor — ele existe para a
   pessoa saber que a decisão existe. O motivo continua no `.rp-envelope` em
   volta e nunca no botão: `<button disabled>` não dispara evento de mouse no
   Chrome, então um `title` preso nele seria motivo escrito que ninguém lê.

   `.perigo` FICA, e é a única divergência deste bloco: o mockup pinta `apagar`
   com o mesmo vermelho das outras três, e aqui ela sai em `--bad`. Ação
   destrutiva com a cor das não-destrutivas é informação a menos, e as duas
   cores são vermelhas — a distância é pequena e o ganho não é. */
.robo-raiz .rp-acao {
  font-size: 11px; letter-spacing: .05em; padding: 3px 6px; border-radius: 3px;
  color: var(--red); text-decoration: none;
}
.robo-raiz .rp-acao:hover:not(:disabled) { background: var(--surf2); }
.robo-raiz .rp-acao.perigo { color: var(--bad); }
.robo-raiz .rp-acao:disabled { color: var(--faint); background: none; }
.robo-raiz .rp-acao:focus-visible { outline: 2px solid var(--red); outline-offset: 1px; }

/* ------------------------------------------------- o estado de uma linha -- */
/* NADA AQUI, E A AUSÊNCIA É A DECISÃO — está escrita para ninguém "consertar".
 *
 * A situação de cada produção (`Na fila`/`Produzindo`/`Concluído`/`Deu erro`/
 * `Cancelado`/`Interrompido`) sai da coluna Situação da lista, do cabeçalho do
 * detalhe e do topo da aba Acompanhar. No mockup ela é a `.pill` (94-103).
 *
 * O P1 criou `.pill` com esses valores e escreveu que dentro do Robô "quem quer
 * estado usa `.pill`". Eu cheguei a trocar as duas emissões destas telas. O P3
 * mediu depois e a premissa caiu: NINGUÉM emite `.pill` — são 14 `.chip` nos
 * quatro arquivos —, e ele pintou `.robo-raiz .chip` com as MESMAS linhas
 * 94-103. Então a pintura já chega aqui pronta, por `.chip`, e eu reverti a
 * troca: emitir `.pill` só nestas duas telas deixaria o mesmo estado com dois
 * nomes, e o `linhaProducao` (histórico simples de reserva, fora do que este
 * passo pode editar) ficaria com um chip redondo no meio de pílulas.
 *
 * Se algum dia o `.pill` passar a ser emitido de verdade, o certo é apagar uma
 * das duas pinturas — nunca manter as duas e somar exceção.
 */
/* ══ fim do P2 ══ */

/* ===== FRENTE C: avatares + canais ===== */
/* Só o que FALTAVA para as duas telas ficarem iguais ao mockup — o resto já foi
   pintado pelo P1 (tokens e primitivas) e pela passada anterior (as seções
   AVATARES/CANAIS, linhas 728-765), e blocos alheios não se editam.
   Fonte: research/conveyer-e-ytfill/robo-mockup.html, `<style>` 3-246, seções
   `s-avatares` (562-598) e `s-canais` (601-633). Valores lidos no arquivo. */

/* `.grp` + `.grp .c` (197-203) — o SEPARADOR DE SEÇÃO, ipsis litteris.
 *
 * ESTE É O TERCEIRO NOME PARA O MESMO OBJETO, e isso está declarado de
 * propósito em vez de escondido: a tela de Ajustes o emite como
 * `.grupo-de-chaves` (+ `.porque`) e a de Custos como `.custos-grupo` (+
 * `.sub`), cada um com a pintura no seu bloco. Nenhum dos dois nomes serve numa
 * lista de avatares — "grupo de chaves" ali é simplesmente falso —, e produção
 * não tinha nome para reusar. `.grp` é o nome do MOCKUP, que é o que os três
 * descrevem.
 *
 * QUEM CONSOLIDAR: o alvo é este seletor, e as outras duas pinturas viram
 * `.grupo-de-chaves, .custos-grupo, .grp` numa regra só. Manter as três e somar
 * exceção é o defeito que este arquivo já registra no `.pill`/`.chip`.
 *
 * A régua no topo é o que faz o separador SEPARAR: sem ela, "Os seus avatares"
 * se lê como legenda do cartão de cima. */
.robo-raiz .grp {
  font-family: var(--mono); font-size: 10px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--dim);
  border-top: 1px solid var(--line); padding-top: 14px; margin: 26px 0 12px;
  display: flex; align-items: center; gap: 10px;
  /* `flex-wrap` NÃO está no mockup e entra assim mesmo: lá o `.c` é uma frase
     curta escrita à mão; aqui ele é a contagem, e num telefone o par
     rótulo + contagem não cabe numa linha só. Sem isto o texto vaza da coluna,
     que é a única regra visual que este passo não pode quebrar. */
  flex-wrap: wrap;
}
/* O `.c` NÃO herda o versalete: ele é uma frase, e frase em caixa alta espaçada
   se lê como continuação do rótulo. */
.robo-raiz .grp .c {
  color: var(--faint); text-transform: none; letter-spacing: 0;
  font-family: var(--sans); font-size: 12px;
}
/* No mockup a lista vem logo depois do cartão e o `margin-top:16px` dela (205) é
   a única separação. Com o separador no meio, os dois somam 28px — mais que
   qualquer distância do mockup. Quem manda aqui é o `.grp`. */
.robo-raiz .grp + .cartoes { margin-top: 0; }

/* `.av .ph` (208-212) — FALTAVA O TAMANHO DA FONTE, e é ele que define o
   desenho do retrato vazio.
 *
 * A regra da passada anterior (747-751) trouxe o gradiente, o `place-items`, a
 * cor e o `letter-spacing:.1em`, mas deixou o `font-size: 2rem` que o
 * `.cartao-avatar .foto-do-avatar` (144-150) dá para o emoji. Com 32px o rótulo
 * do mockup ("ROY") não caberia no quadrado, e era por isso que o retrato ainda
 * mostrava um 🙂 — que é o mesmo defeito visto de outro lado. O mockup diz
 * 10px, e o `avatares.js` passou a escrever o nome ali.
 *
 * `div.` e a mesma especificidade (0,3,1) da regra de cima, de propósito: no
 * cartão COM miniatura este nome é um `<img>`, onde `font-size` não significa
 * nada e `object-fit: cover` é quem manda. */
.robo-raiz .cartao-avatar div.foto-do-avatar { font-size: 10px; }

/* `.card` do canal (629-632): o nome em negrito e a descrição LOGO ABAIXO dele,
   com os 6px do `.hint` (76). A regra que zera essa margem
   (`.linha-canal .resumo .dica`, linha 166) foi escrita quando os dois eram
   irmãos na MESMA linha — ali o zero estava certo, porque a distância vinha do
   `gap`. Agora eles estão empilhados e o zero cola um no outro. */
.robo-raiz .linha-canal .resumo .dica { margin: 6px 0 0; }

/* NADA AQUI PARA `.picks`/`.pick`, E A AUSÊNCIA É A DECISÃO.
   Eles estão no meu escopo "conforme a tela usar", e estas duas telas NÃO os
   usam: no mockup `.pick` só aparece em `s-produzir` (322-353), e em produção o
   nome equivalente (`.opcao-cartao`) não é emitido por `avatares.js` nem por
   `robo_canais.js` — conferido abrindo os dois arquivos, não contando
   ocorrências. Pintar aqui um seletor que nenhuma das minhas telas emite seria
   uma regra que ninguém pode ver falhar. */
/* ===== fim FRENTE C ===== */


/* ===== FRENTE D: ajustes + custos ===== */
/* Segunda passada sobre as MESMAS duas telas que o P3 pintou. Ele acertou a
   maior parte; o que sobrou é o que este bloco fecha, e cada linha cita a
   linha do `research/conveyer-e-ytfill/robo-mockup.html` de onde o número saiu.
   Nada foi lembrado nem arredondado — o arquivo foi aberto.

   DUAS REGRAS AQUI SUPERSEDEM UMA DO P3 (mesma especificidade, e este bloco vem
   depois). Estão nomeadas nos comentários porque valor duplicado em dois pontos
   do mesmo arquivo é o defeito que este repositório já pagou: ele não fica
   duplicado, ele diverge, e aí a pintura passa a ser decidida por ordem de
   linha, que ninguém consegue ler. Quem for consolidar apaga a linha do P3,
   nunca esta. As duas estão listadas no relatório.
   ------------------------------------------------------------------------- */

/* -------------------------------------------------------------- AJUSTES -- */

/* `.key h3{margin:0 0 2px}` + `.key p` (mockup 183-184): entre o NOME da chave
   e a frase que diz para que ela serve o mockup deixa 2px — eles são um par, e
   o par é o que se lê de uma vez. Em produção os dois são irmãos num flex de
   `gap:10px` (`.chave-card`, estilo.css:874-877), e um gap só não consegue
   dizer "10 entre tudo, 2 aqui": os outros vãos do cartão são 10-11 no mockup
   (p->input 11, input->.abre 10) e esses o gap já acerta.

   O puxão fica no `.ch-topo` e NÃO no `.dica` de baixo, de propósito: o P3 já
   declara `margin:0` naquele seletor, e sobrescrever a mesma propriedade dele
   daqui criaria a divergência que o cabeçalho deste bloco descreve. Seletor
   novo, propriedade que ninguém mais toca. */
.robo-raiz .chave-card > .ch-topo { margin-bottom: -8px; }

/* `<button class="btn ghost">Desconectar</button>` (mockup 706). Produção
   emitia `btn sec` — cinza sobre `--surf2`. O `ghost` do mockup é tinta cheia
   sobre transparente com a borda `--line`, e o P1 já o pintou; só faltava a
   marcação pedir por ele. A troca é em `config.js` e não mexe no `onclick`. */

/* --------------------------------------------------------------- CUSTOS -- */

/* AS TRÊS FAMÍLIAS SÃO UMA LINHA SÓ (mockup 721-733), e esta era a diferença
   mais visível da tela.

       <div style="display:flex;flex-wrap:wrap;gap:16px;align-items:center">
         <span style="display:flex;gap:7px;align-items:center">
           <span class="lab" style="margin:0">Cobram por uso</span>
           <span class="pill mute">OpenRouter</span><span class="pill mute">Groq</span>

   Em produção (`estilo.css:2002-2007`) elas eram uma GRADE de `auto-fill`
   `minmax(230px,1fr)` com o rótulo EMPILHADO sobre as pílulas — três colunas
   altas onde o mockup tem uma tira. A leitura muda junto: na tira, "Cobram por
   uso: OpenRouter, Groq" é uma frase; empilhado, o rótulo vira título de coluna
   e as três famílias passam a parecer três seções.

   `flex-wrap` fica: com muitos provedores a tira quebra em vez de espremer o
   nome de um deles. É o que o próprio mockup declara. */
.robo-raiz .custos-familias {
  display: flex; flex-wrap: wrap; gap: 16px; align-items: center;
}
.robo-raiz .custos-familia {
  flex-direction: row; align-items: center; gap: 7px;
}
.robo-raiz .custos-pilhas { gap: 7px; }

/* O cartão do período (mockup 715-734): `gap:10px` na fileira de cima e os 10px
   de `margin-top` que separam a tira das famílias. Em produção eram 6px 12px e
   11px — perto, e "perto" é justamente o que este banho não aceita. O P3 já
   acertou padding, raio e margem do cartão; estas duas propriedades ele não
   tocou, então aqui não há sobreposição. */
.robo-raiz .custos-periodo { gap: 10px; }
.robo-raiz .custos-periodo-topo { gap: 10px; }

/* `<div class="row two" style="margin-bottom:8px">` (mockup 747): os dois
   cartões de plano encostam no que vem embaixo. Sem isto o único espaço era o
   `margin-top:26px` do separador seguinte. */
.robo-raiz .custos-planos { margin-bottom: 8px; }

/* `<div class="grp" style="margin-top:0">` (mockup 745) — o PRIMEIRO separador
   da tela não repete a régua de 26px, porque a frase do custo efetivo logo
   acima já fecha com `margin-bottom:20px` (mockup 743). Somados davam 46px de
   buraco no meio da tela. O seletor é o par exato, então os outros três
   separadores continuam com os 26px do mockup. */
.robo-raiz .custos-efetivo + .custos-grupo { margin-top: 0; }

/* SUPERSEDE `.robo-raiz .custos-filtros { gap: 18px }` (P3, linha 920).
   A linha 770 do mockup escreve o vão na mão — `style="...gap:10px;
   margin-bottom:16px"` —, ou seja a fileira de filtros NÃO usa o `gap:18px`
   default do `.row`. O 18 veio de ler o `.row` e não o `style` de cima dele.

   O nº de colunas fica em `2fr 1fr` (estilo.css:2034) e não nos `2fr 1fr 1fr
   1fr` do mockup: lá são quatro campos (busca, De, Até, provedor) e aqui são
   dois — a tela não tem recorte por data. Inventar os dois campos seria criar
   controle que o servidor não honra, que é a regra 2. */
.robo-raiz .custos-filtros { gap: 10px; margin-bottom: 16px; }

/* AS DUAS TABELAS MORAM DENTRO DE UM CARTÃO, e esta é a outra diferença que se
   via de longe. No mockup (779-780 e 861-862):

       <div class="card" style="padding:0;margin-bottom:22px">
         <div class="scroll"><table> …

   ou seja o `.scroll` (o `.rb-rolagem` daqui) é o MIOLO de um `.card` sem
   padding — fundo `--surf`, borda `--line`, raio 8. Em produção as duas tabelas
   flutuavam direto sobre o chão `--ground`, sem caixa nenhuma: as réguas
   horizontais das linhas ficavam soltas no fundo e a tabela de 15 colunas não
   tinha onde terminar.

   O `padding:0` do mockup é reproduzido por AUSÊNCIA (nada de padding aqui), e
   isso é literal: com ele, o `th{padding:0 12px 8px}` encosta o cabeçalho no
   topo do cartão. É o que o mockup desenha, e não é para "melhorar".

   `overflow-x:auto` já vem do `.rb-rolagem` (linha 186) e é ele que faz o raio
   recortar a tabela larga em vez de deixá-la vazar pelo canto.

   As duas margens do mockup são DIFERENTES (22 na tabela por vídeo, 16 na de
   provedor) porque só a primeira é seguida de dois avisos. `:has()` separa as
   duas sem tocar no JS, e já é usado neste arquivo. Navegador sem `:has()` fica
   com 16 nas duas: 6px, não quebra. */
.robo-raiz .rb-rolagem {
  background: var(--surf); border: 1px solid var(--line);
  border-radius: 8px; margin-bottom: 16px;
}
.robo-raiz .rb-rolagem:has(.custos-tabela) { margin-bottom: 22px; }

/* `<div class="hint" style="margin:0">` DENTRO da célula (mockup 869, 871, 872):
   a segunda linha de "Sai da conta" ("mensalidade, gere ou não gere", "informe
   o plano acima", "valor da resposta, não confirmado na fatura"). O `.dica` da
   casa ganhou `margin:6px 0 0` do P1, e dentro de um `<td>` isso desloca a
   frase da linha dela. `estilo.css:2057` já zera isso, mas SÓ na
   `.custos-tabela` — a tabela por provedor é `class="tabela"` pelada e ficava
   de fora. Aqui vale para as duas. */
.robo-raiz .tabela td .dica { margin: 0; }
/* ===== fim FRENTE D ===== */


/* ===== FRENTE B: producoes ===== */
/* A tela **Produções** (o histórico) e o **detalhe** de uma produção
 * (`/robo-producao/<id>`), segunda passada.
 *
 * Fonte de todo valor: `research/conveyer-e-ytfill/robo-mockup.html`, `<style>`
 * linhas 3-246 e as `<section>` `s-producoes` (496-559) e `s-acompanhar`
 * (391-493). Cada número abaixo foi LIDO daquele arquivo, e a linha está citada
 * em cada bloco.
 *
 * O QUE JÁ ESTAVA CERTO E POR ISSO NÃO SE REPETE AQUI — conferido seletor a
 * seletor no bloco P2 acima e na folha embutida do `robo_producoes.js`, não
 * presumido: a tabela (`table` 132-142 -> `.rp-tab`), a ação de linha (`.lnk`
 * 221-229 -> `.rp-acao`, nos quatro estados), o cabeçalho da produção
 * (`.runhead` 231-238 -> `.rp-cabecalho`), o log (`.log` 166-176 -> `.rp-log`,
 * fundo #08080a) e os quatro estados da `.pill` (94-103 -> `.chip`, no P1).
 * Redeclarar qualquer um deles poria o mesmo valor em dois lugares — e valor
 * duplicado não fica duplicado, ele diverge.
 *
 * A ESPECIFICIDADE AQUI NÃO É DETALHE. A folha do `robo_producoes.js` é
 * injetada em `document.head` DEPOIS do `<link>` desta, então em empate ela
 * ganha. Toda regra abaixo ou tem uma classe a mais que a de lá, ou toca uma
 * propriedade que lá não existe. Onde o empate era possível, está anotado. */

/* ---------------------------------------- o separador de seção (`.grp`) -- */
/* mockup 197-203. Os dois títulos de seção do detalhe ("O log desta produção" e
 * "O que cada cena usou") eram `.cabeca > h1` de 17px — tipografia da CASA, que
 * o mockup não usa em lugar nenhum para separar seção. Lá isso é o `.grp`: mono
 * 10px de versalete, régua em cima, e a nota como irmã na MESMA linha.
 *
 * NOME PRÓPRIO (`rp-grupo`) e não `.grupo-de-chaves`, que é onde o P3 pintou
 * este mesmo desenho: aquele nome é do grupo de CHAVES da tela de Ajustes, e
 * usá-lo para o log de uma produção seria reusar a marcação errada só porque a
 * pintura casa. O prefixo `rp-` é o que estas duas telas já usam (`.rp-tab`,
 * `.rp-log`, `.rp-cabecalho`). CONSEQUÊNCIA DECLARADA: o desenho do `.grp`
 * passa a existir em três seletores desta folha (`.grupo-de-chaves`,
 * `.custos-grupo`, `.rp-grupo`); no dia em que os blocos forem consolidados,
 * os três colapsam num só — nunca se soma exceção a eles.
 *
 * Sem `flex-wrap`: o mockup não o tem, e sem ele o texto quebra DENTRO do item
 * flex em vez de estourar a largura — não há rolagem horizontal em 375px. */
.robo-raiz .rp-grupo {
  font-family: var(--mono); font-size: 10px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--dim);
  border-top: 1px solid var(--line); padding-top: 14px; margin: 26px 0 12px;
  display: flex; align-items: center; gap: 10px;
}
.robo-raiz .rp-grupo .c {
  color: var(--faint); text-transform: none; letter-spacing: 0;
  font-family: var(--sans); font-size: 12px;
}

/* --------------------------------------------------- o topo do detalhe -- */
/* mockup 62-63: `h2{margin:0 0 4px}` + `.sub{margin:0 0 22px}`. O `h2` já sai
 * pintado do P1; falta a distância, e ela não vem sozinha porque o subtítulo
 * vive dentro de um `.cabeca` — é ele que põe o `chip` do estado à direita — e
 * o P1 dá `.robo-raiz .cabeca .sub{margin:3px 0 0}`.
 *
 * O EMPATE FOI DESFEITO, e não deixado declarado. A versão anterior tinha a
 * MESMA especificidade (0,3,0) de `.robo-raiz .cabeca .sub` e vencia só por vir
 * DEPOIS no arquivo — ou seja, mover este bloco para cima apagava o efeito e
 * nada acusaria. É o mesmo mecanismo que fez `.custos-filtros{gap:18px}` virar
 * letra morta, e é a mesma família do defeito que a coluna de 1240px pagou:
 * regra escrita, publicada, e sem efeito nenhum.
 *
 * `.robo-raiz .rp-topo.cabeca .sub` sobe para (0,4,0) — o `.rp-topo` É um
 * `.cabeca` (é ele que põe o chip do estado à direita), então o seletor descreve
 * o elemento com mais precisão em vez de torcer pela ordem. Ganha em qualquer
 * ordem de bloco. */
.robo-raiz .rp-topo { margin-bottom: 22px; }
.robo-raiz .rp-topo.cabeca .sub,
.robo-raiz .rp-topo .sub { margin: 0; }

/* ----------------------------------------------- as ações de uma linha -- */
/* mockup 401 (`<span style="margin-left:auto;display:flex;gap:4px">`, o grupo
 * de ações do `.runhead`) e 517-522 (a célula `td.acoes` da lista, onde os
 * `<button class="lnk">` são irmãos separados só pelo espaço da marcação).
 *
 * `gap: 10px` espalhava as quatro ações (`abrir · mp4 · retomar · apagar`) por
 * quase o dobro da largura que elas ocupam no mockup, e o efeito é o oposto do
 * pretendido: quatro links soltos se lêem como quatro colunas, não como um
 * conjunto. 4px é o valor que o mockup declara.
 *
 * `.rp-acoes` na folha embutida é (0,1,0); esta é (0,2,0) e ganha. */
.robo-raiz .rp-acoes { gap: 4px; }

/* ------------------------------------------------- a linha do histórico -- */
/* mockup 514: o título do vídeo é um `<b>`, ou seja peso 700. A folha embutida
 * pinta `.rp-titulo` com 600 — meio degrau abaixo, numa coluna cujo trabalho é
 * ser o âncora visual da linha.
 * TRÊS classes de propósito: o `.rp-tab .rp-titulo` de lá é (0,2,0) e, por ser
 * injetado depois, ganharia de um seletor de duas. */
.robo-raiz .rp-tab .rp-titulo { font-weight: 700; }

/* mockup 558: `<p class="hint" style="margin-top:12px">` embaixo da tabela, com
 * `<b style="color:var(--dim)">abrir</b>` — o negrito é um degrau mais CLARO
 * que a frase em volta (`--faint`), e não mais escuro.
 * A margem vai a ZERO porque `.rp-lista` é uma coluna flex com `gap: 12px`: a
 * distância do mockup já está lá, e os 6px de `.dica` (P1) somavam por cima,
 * dando 18. */
.robo-raiz .rp-lista > .dica { margin: 0; }
.robo-raiz .rp-lista > .dica b { color: var(--dim); }

/* mockup 451: `<p class="hint" style="margin-top:14px">` logo abaixo do log.
 * Empate com `.robo-raiz .dica` (0,2,0) do P1, resolvido por ordem de linha no
 * mesmo arquivo — mesma observação do `.rp-topo` acima. */
.robo-raiz .rp-nota-log { margin: 14px 0 0; }

/* mockup 465/472/479/486: o detalhe da origem é `<span class="hint"
 * style="display:inline">`, na mesma linha e depois de um " · ". Como `.dica`
 * nasce em bloco, sem isto ele quebraria a célula em duas alturas. */
.robo-raiz .rp-tab .rp-inline { display: inline; margin: 0; }
/* ===== fim FRENTE B ===== */

/* ===== FRENTE A: produzir + acompanhar ===== */
/* As duas telas que vivem no `robo.js`: o formulário do pedido e o
   acompanhamento de uma produção. Só o que FALTAVA para elas ficarem iguais ao
   desenho — os tokens e as primitivas são do P1, a régua/log/tabela são do P2,
   e bloco alheio não se edita.

   Fonte de todo valor: research/conveyer-e-ytfill/robo-mockup.html, `<style>`
   3-246, seções `s-produzir` (269-388) e `s-acompanhar` (391-493). Cada número
   abaixo foi LIDO daquele arquivo, com a linha citada ao lado. */

/* ---------------------------------------------- a coluna de uma tela só --
 * O `.wrap` do mockup é um BLOCO: as `.row` se separam pelo `margin-bottom:18px`
 * delas (77), e não por um `gap` do pai. As duas telas eram
 * `flex-direction:column; gap:14px` (estilo.css:1675), e o P1 subiu esse gap
 * para 18 — só que gap e margem SOMAM: cada `.row` daria 36px de respiro, o
 * dobro do desenho. Voltando a BLOCO, quem manda é a margem de cada elemento,
 * exatamente como no arquivo. */
.robo-raiz .rb-produzir,
.robo-raiz .rb-acompanhar { display: block; }

/* ------------------------------------------------------------ produzir -- */

/* O contador de palavras é o `.hint` do campo (293) e agora emite `.ajuda`,
   que o P1 já pinta. Nada a declarar aqui — fica dito para quem procurar. */

/* `rows="7"` (292) é a altura do desenho; o `min-height:12rem` do estilo.css
   (1681) é maior e teria a última palavra, transformando o `rows` em enfeite.
   `resize:vertical` continua valendo, então quem prefere ver o roteiro inteiro
   arrasta. `line-height` volta para o 1.55 do corpo do mockup (19) — o
   estilo.css usa 1.5, e a diferença aparece somada em sete linhas. */
.robo-raiz .rb-escrever textarea { min-height: 0; line-height: 1.55; }

/* A GAVETA DAS OPÇÕES AVANÇADAS VIRA A FAIXA `.grp` (197-203, 318).
 *
 * No mockup a área avançada é sempre aberta e o `.grp` é um separador estático.
 * Aqui ela CONTINUA sendo um `<details>` — divergência já declarada pelo P1, e
 * mexer nisso mudaria comportamento. O que muda é só a pintura: a caixa
 * emoldurada some e sobra a régua com o rótulo em cima, como no desenho.
 *
 * O `.grp` é o da FRENTE C, reusado inteiro. Uma segunda cópia dos mesmos
 * valores divergiria na primeira edição — é o defeito que este arquivo já
 * registra no `.pill`/`.chip`. */
.robo-raiz .rb-produzir .rb-avancadas {
  border: 0; background: transparent; padding: 0; border-radius: 0;
  margin: 0 0 18px;
}
/* O MARCADOR DO `<details>` PRECISA VOLTAR. `.grp` é `display:flex`, e com isso
   o Chrome deixa de desenhar o triângulo — a linha ficaria idêntica a um título
   estático, e o único jeito de descobrir que ela abre seria clicando por acaso.
   Ele volta como texto, no `::before`, que num contêiner flex é o primeiro item
   e herda o `gap:10px` do próprio `.grp`. */
.robo-raiz .rb-avancadas > summary { cursor: pointer; list-style: none; }
.robo-raiz .rb-avancadas > summary::-webkit-details-marker { display: none; }
.robo-raiz .rb-avancadas > summary::before { content: "\25B8"; color: var(--red); }
.robo-raiz .rb-avancadas[open] > summary::before { content: "\25BE"; }

/* Os campos avançados seguem o mesmo respiro de 18px das linhas de cima (77).
   O `margin-top:12px` do estilo.css (1787) sai porque o `.grp` já entrega
   `margin-bottom:12px` — os dois somados dariam 24. */
.robo-raiz .rb-avancado { gap: 18px; margin-top: 0; }
.robo-raiz .rb-avancado .rb-solo { gap: 18px; }

/* DUAS OPÇÕES OCUPAM A LINHA INTEIRA (350): o mockup crava `repeat(3,1fr)` na
   grade de escolhas (118) e sobrescreve para `1fr 1fr` no único grupo de dois
   cartões. Sem isto os dois ficam com 2/3 da largura e um buraco à direita.
   O colapso de 820px precisa ser repetido porque este seletor é mais
   específico que o do P1 — regra mais específica escrita depois não "some" no
   telefone, ela ganha lá também. */
.robo-raiz .rb-cartoes.duas { grid-template-columns: 1fr 1fr; }
@media (max-width: 820px) {
  .robo-raiz .rb-cartoes.duas { grid-template-columns: 1fr; }
}

/* O NÚMERO NÃO CABE EM 8rem QUANDO ELE É UM CAMPO DE LINHA. No mockup
   "Segundos por cena" é um `.fld` de largura inteira dentro de uma `.row.three`
   (361-366); o estilo.css o limita a 8rem (1803), o que deixa o rótulo com o
   dobro da largura do campo que ele nomeia. */
.robo-raiz .rb-avancado .campo input[type="number"] { max-width: none; }

/* AS PÍLULAS ERAM VERDES E FICARAM DE FORA DA REPINTURA. O P1 pintou
   `.rb-abas .pchip` (a barra) e o `.rb-cartao` (as escolhas em cartão), mas o
   MESMO `.pchip` também é a forma dos campos de escolha curta dentro das opções
   avançadas — e lá ele continuava com o `.pchip.on` VERDE do estilo.css (869),
   ao lado de cartões cuja seleção é vermelha. Duas cores para "isto está
   escolhido" na mesma tela é o aluno aprendendo o produto duas vezes.
   Os valores são os do `.nav button` (47-54) para o repouso e os do `.pick.on`
   (125) para o escolhido — as duas linguagens que o mockup usa. */
.robo-raiz .rb-pilulas .pchip {
  font-family: var(--mono); font-size: 11.5px; letter-spacing: .06em;
  text-transform: uppercase; color: var(--dim);
  background: transparent; border: 1px solid var(--line); border-radius: var(--r);
  padding: 7px 11px; cursor: pointer; transition: color .12s, background .12s;
}
.robo-raiz .rb-pilulas .pchip:hover:not(:disabled) {
  color: var(--ink); background: var(--surf2);
}
.robo-raiz .rb-pilulas .pchip.on {
  color: var(--ink); border-color: var(--red); background: #180d0f;
}
.robo-raiz .rb-pilulas .pchip:disabled { opacity: .55; cursor: not-allowed; }
.robo-raiz .rb-pilulas .pchip:focus-visible {
  outline: 2px solid var(--red); outline-offset: 1px;
}

/* --------------------------------------------------------- acompanhar -- */

/* O `.runhead` (231-238). O `.rb-topo` era um flex de duas pontas com o título
   dentro; agora ele é a FAIXA emoldurada com os campos, e o título subiu para o
   `h2` que o mockup usa (392).
   `justify-content` volta para o começo: o `space-between` do estilo.css (1684)
   espalharia os campos pela largura toda, e quem vai para a direita é só o
   estado, pelo `margin-left:auto` — o mesmo recurso do desenho (401). */
.robo-raiz .rb-topo {
  display: flex; flex-wrap: wrap; gap: 10px 18px; align-items: baseline;
  justify-content: flex-start;
  border: 1px solid var(--line); background: var(--surf);
  border-radius: 8px; padding: 13px 16px; margin-bottom: 18px;
}
.robo-raiz .rb-topo .rb-k {
  font-family: var(--mono); font-size: 10px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--dim); margin-right: 6px;
}
.robo-raiz .rb-topo .rb-v { font-size: 13.5px; font-variant-numeric: tabular-nums; }
.robo-raiz .rb-topo .rb-ficha-estado { margin-left: auto; }

/* A linha que continua a régua ("garimpando… · 12 de 264 cenas · 26%") e o
   batimento. Nenhuma das duas está no mockup — a régua de lá é estática —,
   então a pintura sai da `.sub` (63): 13px, `--dim`, com o nome da fase em
   `--ink` para ela não se perder no meio da frase. */
.robo-raiz .rb-passo { font-size: 13px; color: var(--dim); margin-bottom: 6px; }
.robo-raiz .rb-passo b { color: var(--ink); font-weight: 620; }
.robo-raiz .rb-pulso { margin-bottom: 14px; }

/* O PONTO PARA DE PISCAR. Dono: *"essa linha piscando em cinza precisa melhorar
   10000x"*. Ele pulsa a cada 1,6 s numa tela que fica aberta por HORAS, e num
   painel de produção nada pode se mexer sem estar dizendo alguma coisa.

   Só a ANIMAÇÃO morre, e só aqui dentro: a frase fica inteira ("sem novidade há
   40 s"), porque foi ela que resolveu o defeito medido de a tela ficar 17
   minutos muda e o aluno ler isso como travamento. O `@keyframes rb-bate` de
   `estilo.css` continua vivo — `.rb-fase.agora` é o segundo consumidor dele, e
   apagá-lo apagaria a marca de "você está aqui" da régua.

   Especificidade 0,2,1 contra os 0,1,1 de `estilo.css:1694`: ganha sem
   `!important`, e sem tocar no resto do site. */
.robo-raiz .rb-pulso::before { animation: none; }

/* A COBERTURA, separada da fase. O número que dizia "157 de 157 cenas · 100%"
   morava colado no nome da fase, e as duas metades vinham de lugares
   diferentes: o contador conta CENAS COM IMAGEM e o rótulo fala do GARIMPO.
   Numa retomada toda cena já tem imagem da passada anterior, então a barra
   crava 100 % no segundo em que o garimpo começa — e o dono leu isso, com
   razão, como "diz que está tudo pronto e não está". Agora são dois nós. */
.robo-raiz .rb-cobertura, .robo-raiz .rp-cobertura {
  font-size: 13px; color: var(--dim); margin-bottom: 6px;
  font-variant-numeric: tabular-nums;
}
.robo-raiz .rb-cobertura b, .robo-raiz .rp-cobertura b {
  color: var(--ink); font-weight: 620;
}

/* O NÚMERO DE RELANCE. "Quanto falta?" é a pergunta que se faz de longe, e ela
   estava saindo como texto de 13 px perdido acima do log. */
.robo-raiz .rb-cobre-n {
  font-size: 34px; line-height: 1; font-weight: 640; color: var(--ink);
  font-variant-numeric: tabular-nums; margin-right: 9px;
}
.robo-raiz .rb-cobre-q { font-size: 14px; color: var(--dim); }
.robo-raiz .rb-cobre-barra {
  display: block; height: 6px; border-radius: 3px; background: var(--surf3);
  margin-top: 12px; overflow: hidden; max-width: 520px;
}
/* A barra é BRANCA, não vermelha: vermelho aqui significa footage real, e uma
   barra de progresso vermelha faria o olho procurar procedência no cromo. */
.robo-raiz .rb-cobre-barra > i { display: block; height: 100%; background: var(--ink); }

/* ═══════════ A MONTAGEM ════════════════════════════════════════════════════
   O contador de cima fecha em 100 % quando a última cena ganha imagem — e é aí
   que COMEÇA a montagem, que na máquina fraca é a fase mais longa do vídeo.
   Medido no MacBook de um aluno: 1h58 com a tela imóvel em "409 de 409 · 100%".

   DELIBERADAMENTE MENOR que o número de cima. São duas medidas: a de cima
   responde a pergunta do produto ("quanto do vídeo já é meu?") e esta responde
   a do momento ("está andando?"). Empatar os dois tamanhos faria o olho
   escolher no chute qual dos dois é o assunto.
   AS DUAS TELAS DE DETALHE GANHAM A LINHA, e por isso o seletor é duplo. O
   `robo.js` documenta a armadilha com todas as letras — *"duas telas divergem,
   e foi assim que a de acompanhar ganhou o log e a de histórico não"*. */
.robo-raiz .rb-montagem, .robo-raiz .rp-montagem {
  font-size: 13px; color: var(--dim); margin-bottom: 6px;
  font-variant-numeric: tabular-nums;
}
/* Vazia, ela não pode ocupar espaço: a linha só existe durante a montagem, e
   uma folga fantasma no resto do run empurraria a tela inteira sem motivo. */
.robo-raiz .rb-montagem:empty, .robo-raiz .rp-montagem:empty { margin: 0; }
.robo-raiz .rb-mont-nome, .robo-raiz .rp-montagem b { color: var(--ink); }
.robo-raiz .rp-montagem b { font-weight: 620; }
.robo-raiz .rb-mont-pct { color: var(--ink); font-weight: 620; margin-left: 8px; }
.robo-raiz .rb-mont-det { margin-left: 8px; }
/* A barra da montagem herda `.rb-cobre-barra` e só encolhe a folga de cima:
   ela pertence à linha dela, e a folga cheia a soltaria no meio dos dois nós. */
.robo-raiz .rb-montagem .rb-cobre-barra { margin-top: 7px; }

/* ═══════════ O PLACAR AO VIVO ══════════════════════════════════════════════
   De onde vieram as cenas ENQUANTO o robô ainda trabalha.

   Ele não repete a fita do placar do vídeo pronto de propósito. Duas barras
   proporcionais na mesma tela, medindo coisas diferentes, é a versão visual do
   "157 de 157 · 100 %" que o dono flagrou: mesma forma, denominador diferente.
   Aqui não há geometria proporcional nenhuma — só os termos e uma frase.

   NADA DE `--faint` NOS RÓTULOS. Medido sobre `--surf` (#141417): `--faint`
   (#5f5f68) dá 2,91:1, abaixo do piso de 4,5 para texto pequeno; `--dim`
   (#8e8e96) dá 5,66:1. O token global não foi mexido — ele é usado na folha
   inteira e trocá-lo aqui seria mudar telas que ninguém pediu. */
.robo-raiz .rb-placar { margin-top: 18px; margin-bottom: 20px; }
.robo-raiz .rb-placar-topo {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 14px; flex-wrap: wrap; margin-bottom: 12px;
}
.robo-raiz .rb-placar-rot,
.robo-raiz .rb-placar-den {
  font-family: var(--mono); font-size: 10px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--dim);
}
.robo-raiz .rb-placar.sem-base .hint { margin: 6px 0 0; max-width: 62ch; }

.robo-raiz .rb-termos {
  display: flex; gap: 22px; flex-wrap: wrap; align-items: baseline;
}
.robo-raiz .rb-termo { display: flex; gap: 8px; align-items: baseline; }
.robo-raiz .rb-termo > b {
  font-size: 22px; font-weight: 700; line-height: 1;
  font-variant-numeric: tabular-nums;
}
.robo-raiz .rb-termo-nome { font-size: 13px; color: var(--dim); }
.robo-raiz .rb-bolha {
  width: 9px; height: 9px; border-radius: 2px; flex: none;
  transform: translateY(-1px); background: var(--fonte-cromo);
}
.robo-raiz .t-filmagem .rb-bolha     { background: var(--fonte-filmagem); }
.robo-raiz .t-filmagem > b           { color: var(--fonte-filmagem); }
.robo-raiz .t-foto .rb-bolha         { background: var(--fonte-foto); }
.robo-raiz .t-foto > b               { color: var(--fonte-foto); }
.robo-raiz .t-ia .rb-bolha           { background: var(--fonte-ia); }
.robo-raiz .t-ia-video .rb-bolha     { background: var(--fonte-ia-video); }
.robo-raiz .t-ia > b                 { color: var(--fonte-ia); }
.robo-raiz .t-ia-video > b           { color: var(--fonte-ia-video); }
.robo-raiz .t-apresentador .rb-bolha { background: var(--fonte-avatar); }
.robo-raiz .t-apresentador > b       { color: var(--fonte-avatar); }
.robo-raiz .t-outras > b,
.robo-raiz .t-indefinido > b         { color: var(--dim); }

/* AINDA EM DISPUTA — apartado por um fio, SEMPRE na própria linha.
   A primeira versão o deixava em linha com um fio em pé, e quando os termos
   não cabiam ele quebrava sozinho e o fio virava um risco solto à esquerda.
   Separação que depende de caber some justo na tela estreita, que é onde ela
   mais precisa existir. */
.robo-raiz .rb-disputa {
  display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap;
  width: 100%; margin-top: 13px; padding-top: 12px;
  border-top: 1px solid var(--line);
}
.robo-raiz .rb-disputa > b {
  font-size: 22px; font-weight: 700; line-height: 1;
  font-variant-numeric: tabular-nums; color: var(--dim);
}
.robo-raiz .rb-quadra {
  width: 9px; height: 9px; flex: none; transform: translateY(-1px);
  background: var(--risco-disputa); box-shadow: inset 0 0 0 1px var(--line);
}

.robo-raiz .rb-placar-faixa {
  margin: 16px 0 0; font-size: 14px; color: var(--dim); max-width: 62ch;
}
.robo-raiz .rb-placar-faixa .pct {
  font-size: 17px; font-weight: 700; color: var(--ink);
  font-variant-numeric: tabular-nums;
}

/* O BLOCO DO PLACAR — cartão, e não texto solto no meio da página.
   A primeira versão pôs os quatro números crus embaixo do log e o dono riu:
   *"ué, tem nada a ver com o mockup"*. Ele estava certo — eu tinha portado o
   DADO e a honestidade, e deixado o desenho para trás. */
.robo-raiz .rp-placar {
  border: 1px solid var(--line); background: var(--surf);
  border-radius: var(--r); padding: 16px 18px;
}

/* A FITA. Ela é o placar que se lê de longe: a proporção aparece sem contar
   nada, e é a proporção que a meta de 50-60 % cobra. */
.robo-raiz .rp-fita {
  display: flex; flex-wrap: nowrap; gap: 0;
  height: 22px; border-radius: 6px; overflow: hidden;
  background: var(--surf3); margin-bottom: 16px;
}
/* BLINDADA de proposito. A primeira versao saiu com a ultima fatia SOLTA e
   arredondada, e nenhuma regra do repositorio explicava isso -- entao em vez de
   continuar adivinhando qual seletor herdado a pegava, as quatro propriedades
   que poderiam produzir aquilo (gap, margem, raio e encolhimento) sao zeradas
   AQUI, onde se ve. Defender custa menos que cacar. */
.robo-raiz .rp-fita > i {
  display: block; height: 100%; border-radius: 0; margin: 0;
  flex: 0 0 auto; min-width: 0;
}
/* AS DUAS MÍDIAS DO MATERIAL REAL, na fita do placar final. As variáveis já
   existiam (o placar AO VIVO as usa desde a 0.1.13); o que faltava era o placar
   final poder separá-las — ele publicava só a soma, e foi ela que produziu os
   "33 reais" de um vídeo com 13 clipes e 21 fotos. `.real` fica para job antigo,
   que não declara mídia nenhuma. */
.robo-raiz .rp-fita .filmagem { background: var(--fonte-filmagem); }
.robo-raiz .rp-fita .foto     { background: var(--fonte-foto); }
.robo-raiz .rp-fita .real   { background: var(--fonte-real); }
.robo-raiz .rp-fita .ia     { background: var(--fonte-ia); }
.robo-raiz .rp-fita .ia-video { background: var(--fonte-ia-video); }
.robo-raiz .rp-fita .avatar { background: var(--fonte-avatar); }
.robo-raiz .rp-fita .outras { background: var(--fonte-cromo); }

/* O PLACAR DE FONTES. Grade que preenche a largura (`auto-fit`), nunca colunas
   fixas: num monitor largo a grade fixa joga metade da tela fora. */
.robo-raiz .rp-fontes {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(132px, 1fr));
  gap: 10px;
}
.robo-raiz .rp-fonte { display: flex; gap: 9px; align-items: flex-start; }
.robo-raiz .rp-fonte .pt {
  width: 10px; height: 10px; border-radius: 3px; margin-top: 6px; flex: none;
}
.robo-raiz .rp-fonte .n {
  font-size: 21px; line-height: 1.15; color: var(--ink); font-weight: 620;
  font-variant-numeric: tabular-nums;
}
.robo-raiz .rp-fonte .q { display: block; font-size: 12.5px; color: var(--dim); }
.robo-raiz .rp-fonte .p { font-family: var(--mono); font-size: 11px; color: var(--faint); }
.robo-raiz .rp-fonte.filmagem .pt { background: var(--fonte-filmagem); }
.robo-raiz .rp-fonte.foto .pt     { background: var(--fonte-foto); }
.robo-raiz .rp-fonte.real .pt   { background: var(--fonte-real); }
.robo-raiz .rp-fonte.ia .pt     { background: var(--fonte-ia); }
.robo-raiz .rp-fonte.ia-video .pt { background: var(--fonte-ia-video); }
.robo-raiz .rp-fonte.avatar .pt { background: var(--fonte-avatar); }
.robo-raiz .rp-fonte.outras .pt { background: var(--fonte-cromo); }

/* O CAMINHO DO ARQUIVO, em bloco próprio e selecionável. Ele já aparecia, mas
   enterrado dentro de um aviso verde de uma linha só — dava para ler e não para
   usar. O mp4 não sobe (fica no PC do aluno), então o caminho É a entrega. */
.robo-raiz .rp-caminho {
  font-family: var(--mono); font-size: 11.5px; color: var(--dim);
  background: #08080a; border: 1px solid var(--line); border-radius: var(--r);
  padding: 9px 11px; margin: 8px 0; word-break: break-all; user-select: all;
}

/* `<p class="hint" style="margin-top:14px">` (451), logo abaixo do log. */
.robo-raiz .rb-fecha-pagina { margin: 14px 0 18px; }
.robo-raiz .rb-acompanhar > .rb-acoes { margin-bottom: 18px; }

/* ------------------------------------------- baixar o robô (1ª vez) -- */
/* ENQUANTO NÃO HÁ MÁQUINA LIBERADA, ESTA SEÇÃO É O ASSUNTO DA TELA. Ela ganha o
   `.card` do mockup (82-85) — que o P1 já pinta — e sobe para antes do
   formulário. Aqui só entra o que o `.card` não resolve.
   Com máquina conectada a classe sai no JS e ela volta a ser o bloco discreto
   de sempre: nenhuma destas regras casa, e não há estado a desfazer. */
.robo-raiz .rb-primeira-vez { margin-bottom: 22px; }
/* O bloco do download é um cartão DENTRO do cartão. Com os dois em `--surf` só
   a borda os separaria; `--surf2` é o degrau que o mockup usa para empilhar
   superfície sobre superfície (e o mesmo do `.pill.mute`, 103). */
.robo-raiz .rb-primeira-vez .baixar { background: var(--surf2); }

/* WINDOWS OU MAC. Duas fichas lado a lado, e não um `<select>`: são duas
   opções, sempre — abrir um menu para escolher entre dois itens é um clique a
   mais para ver metade da informação. Lado a lado o aluno lê o requisito de
   cada uma sem interagir.
   `auto-fit` com piso, nunca `repeat(2, ...)`: no celular as duas empilham
   sozinhas, e é a mesma regra de grade por quantidade que o painel já paga. */
.robo-raiz .rb-plats {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 8px; margin-bottom: 10px;
}
.robo-raiz .rb-plat {
  display: flex; flex-direction: column; gap: 2px; text-align: left;
  padding: 10px 12px; border-radius: var(--r); cursor: pointer;
  background: var(--surf2); border: 1px solid var(--line); color: var(--ink);
  font: inherit;
}
.robo-raiz .rb-plat b { font-size: 13px; }
.robo-raiz .rb-plat span { font-size: 11.5px; color: var(--dim); line-height: 1.4; }
.robo-raiz .rb-plat:hover:not(.off) { border-color: var(--line-soft); background: var(--surf3); }
/* A ESCOLHIDA usa a borda da marca, não preenchimento: o botão de baixar ao
   lado já é a única área vermelha cheia da tela, e duas coisas gritando no
   mesmo bloco fazem o olho não saber qual é a ação. */
.robo-raiz .rb-plat.on { border-color: var(--marca); box-shadow: inset 2px 0 0 var(--marca); }
/* SEM PACOTE: apagada e sem mão de clique — ela informa, não age. Continua
   LEGÍVEL (nada de `opacity` baixa no bloco todo), porque a frase dela é
   justamente o que a pessoa precisa ler. */
.robo-raiz .rb-plat.off { cursor: default; background: transparent; border-style: dashed; }
.robo-raiz .rb-plat.off b { color: var(--dim); }

/* O MINI TUTORIAL. Lista numerada de verdade (`<ol>`), porque a ordem é a
   informação: os quatro passos só funcionam nessa sequência.
   O número em vermelho é a única cor da lista — é ele que faz o olho achar o
   passo em que parou. */
.robo-raiz .rb-tutorial { display: flex; flex-direction: column; gap: 10px; }
.robo-raiz .rb-passos {
  margin: 0; padding-left: 22px; color: var(--dim); font-size: 13px;
  line-height: 1.55;
}
.robo-raiz .rb-passos li { margin-bottom: 9px; }
.robo-raiz .rb-passos li:last-child { margin-bottom: 0; }
.robo-raiz .rb-passos li::marker {
  color: var(--red); font-family: var(--mono); font-size: 12px;
}
/* A ressalva do aviso azul do Windows: é a linguagem do `.pick .why` (129) —
   `--warn`, 11.5px —, que é como o mockup escreve "atenção a este detalhe" sem
   virar erro. Ela some sozinha quando o instalador for assinado. */
.robo-raiz .rb-passo-nota { color: var(--warn); font-size: 11.5px; margin-top: 5px; }

/* O PDF É SECUNDÁRIO DE PROPÓSITO — `.lnk` do mockup (221-229), nunca o `.btn`
   vermelho. O botão vermelho desta seção é "Baixar o robô"; um segundo botão
   com o mesmo peso ao lado faria o aluno baixar o passo a passo achando que
   baixou o robô, e ele só descobriria procurando um instalador que não existe.
   O sublinhado do `.link` da casa sai pelo mesmo motivo que saiu no `.rp-acao`
   do P2: com outros links por perto, sublinhado funde tudo numa frase só. */
.robo-raiz .rb-pdf {
  min-height: 32px; display: inline-flex; align-items: center; gap: 6px; align-self: flex-start;
  font-family: var(--mono); font-size: 11px; letter-spacing: .05em;
  color: var(--red); text-decoration: none;
  padding: 3px 6px; border-radius: 3px; border: 0; background: none;
}
.robo-raiz .rb-pdf:hover { background: var(--surf2); }
.robo-raiz .rb-pdf:focus-visible { outline: 2px solid var(--red); outline-offset: 1px; }
/* ===== fim FRENTE A ===== */

/* =====================================================================
   FRENTE — A CAIXA DE PREFLIGHT DOS AJUSTES (2026-08-16)
   =====================================================================
   Dono, sobre o print: "ta muito feio esse campo em vermelho, precisa ficar
   mais organizado e mais bonito com as informações corretas."

   O que existia: UMA `.aviso.erro`, e dentro dela todo o preflight junto num
   `join('<br>')` — o bloqueio, cada chave que falta, o fecho sobre o conjunto e
   o aviso do Pexels, todos no mesmo vermelho e no mesmo peso de texto.

   A CAIXA (`.note` nos três tons) NÃO É NOVA: ela já está pintada acima, nas
   linhas do mockup 105-115, e é a mesma primitiva. O que entra aqui é só o
   MIOLO. Nenhuma regra abaixo repete cor, raio ou espessura já declarados lá em
   cima — valor duplicado neste arquivo é o defeito que o próprio bloco do
   `.pill`/`.chip` já teve de consertar.

   PREFIXO `prevoo-` E NÃO `pf-`: `estilo.css:1391-1415` já define `.pf-topo`,
   `.pf-capa`, `.pf-titulo`, `.pf-lado` — a tela de Perfil. Um `.prevoo-titulo`
   escrito como `.pf-titulo` herdaria `font-size: 1rem; font-weight: 700` do
   Perfil e ainda entraria na lista de colisões que
   `testes_dos_ajustes.py` cobra. Conferido: `prevoo` não aparece em nenhuma das
   duas folhas.

   OS FILETES SAEM DE `currentColor`, não de `--line`. O `--line` (#2a2a30) é
   cinza-azulado e some sobre `--bad-soft` (#2d1416) e `--warn-soft` (#2b2110) —
   dentro da caixa colorida o único separador que funciona nos três tons é o
   próprio texto rebaixado. `color-mix` já é o idioma desta folha
   (`.opcao-cartao.on`, mais acima). */
.robo-raiz .prevoo {
  /* O `.note` é flex; sem isto o item de texto longo se recusa a encolher e
     estoura a largura da caixa em vez de quebrar linha. */
  min-width: 0;
}

/* O rótulo existe para a diferença bloqueio × degradação NÃO viver só na cor —
   quem não separa vermelho de amarelo lê a palavra. */
.robo-raiz .prevoo-rotulo {
  font-family: var(--mono); font-size: 10px; letter-spacing: .13em;
  text-transform: uppercase; color: var(--dim); margin-bottom: 6px;
}
.robo-raiz .note.warn .prevoo-rotulo { color: var(--warn); }

.robo-raiz .prevoo-titulo { margin: 0; }

.robo-raiz .prevoo-lista { list-style: none; margin: 10px 0 0; padding: 0; }

/* Filete SÓ ENTRE itens. Um filete no primeiro o encostaria no título e a lista
   pareceria começar antes de acabar a frase de cima. */
.robo-raiz .prevoo-item + .prevoo-item {
  margin-top: 9px; padding-top: 9px;
  border-top: 1px solid color-mix(in srgb, currentColor 14%, transparent);
}

/* O nome da chave é RÓTULO, na mesma língua do `.lab` do mockup (64-68): mono,
   caixa alta, espaçado. É ele que se lê de relance na vertical. */
.robo-raiz .prevoo-nome {
  display: block; font-family: var(--mono); font-size: 10.5px;
  letter-spacing: .13em; text-transform: uppercase; color: var(--ink);
  margin-bottom: 3px;
}

/* Rebaixar o motivo só vale quando existe um nome ACIMA dele para hierarquizar.
   No item de aviso o motivo é o único texto da linha — deixá-lo em `--dim` ali
   apagaria a informação inteira em vez de subordiná-la a alguma coisa. */
.robo-raiz .prevoo-porque { display: block; color: var(--ink); }
.robo-raiz .prevoo-nome + .prevoo-porque { color: var(--dim); }

/* O FECHO É RODAPÉ DA CAIXA, e é isso que a regra impede de voltar a acontecer:
   como último item da lista, "A outra obrigatória já está configurada." ficava
   colado no Groq e se lia como se fosse sobre o Groq. Filete + recuo zero +
   texto rebaixado o devolvem ao escopo dele, que é o conjunto das chaves. */
.robo-raiz .prevoo-fecho {
  margin: 10px 0 0; padding-top: 9px;
  border-top: 1px solid color-mix(in srgb, currentColor 14%, transparent);
  color: var(--dim); font-size: 12.5px;
}
/* ===== fim FRENTE preflight ===== */

/* ══════════════════ FRENTE · A TELA DE CANAIS, REPINTADA ═══════════════════
 *
 * Dono (2026-08-16): *"essa tela da configuração do canal precisa ficar mais
 * bonita e mais simples de entender, ta muito preto e cinza, ficou esquisito,
 * faltou a tonalidade vermelha"*.
 *
 * ─── A REGRA DO VERMELHO, DECLARADA ANTES DA PRIMEIRA LINHA ───
 *
 * **Vermelho é ESTRUTURA. Preenchimento sólido existe UM POR CARTÃO.**
 *
 * Vermelho em tudo não dá quinze vezes mais destaque — dá zero, e ANULA o único
 * ponto que precisa dele. Nenhuma regra deste bloco pinta fundo vermelho em
 * coisa nenhuma: o cheio é só o `.btn.pri`, que já existia. O que o vermelho
 * ganha aqui é o papel que ele já tem no resto do Robô — MARCAR a estrutura:
 *
 *     tique de 34px na régua de cada seção   (novo — ver a CONTA abaixo)
 *     o triangulo da gaveta "Avançado"       (paridade com o Produzir, que já
 *                                             o tem em `.rb-avancadas`, l. 1556)
 *     foco de teclado do campo               (já existia, intocado)
 *     o link "ver a licenca"                 (já existia — ver `.rc-faixa a`)
 *     o botão principal, sólido              (já existia, INTOCADO)
 *
 * ─── AS DUAS CONTAS QUE ESTAVAM ERRADAS AQUI, E A MEDIDA CERTA ───
 *
 * Este comentário dizia **"5 marcas em toda a tela"** e **"preenchimento sólido
 * existe UM só na tela"**. As duas frases foram contadas na tela renderizada e
 * as duas são falsas — e falsas do mesmo jeito: elas descrevem o CARTÃO e
 * afirmam a TELA. A tela tem uma lista de canais embaixo, e ela cresce.
 *
 *     tiques      6 com zero canais (5 no cartão de criar + o da lista),
 *                 e 5×(N+1)+1 com N canais salvos — cada canal aberto para
 *                 edição desenha o formulário inteiro de novo
 *     sólidos     um por CARTÃO: "Criar canal" mais um "Salvar" por canal
 *                 que estiver aberto
 *
 * Contar errado aqui não é detalhe de prosa: a regra do vermelho SE APOIA na
 * contagem, e o teste que a "trava" percorre só o cartão de criar — então ele
 * confirmava a frase do cartão e deixava a frase da tela passar. A afirmação
 * que sobrevive à medição é a de cima, por cartão.
 *
 * O QUE ESTE BLOCO **NÃO** TOCA, e a ausência é decisão medida: a aba acesa
 * (`.rb-abas .pchip.sai.on`, hoje em `--faint`) é o candidato mais óbvio a
 * ganhar vermelho — é a única coisa da tela que responde "onde eu estou?" e é a
 * mais apagada de todas. Ela é emitida por `robo.js` nas SETE telas do Robô, e
 * mexer nela repintaria máquinas e produções, que outras frentes estão editando
 * neste minuto. Fica registrado para quem puder mexer nas sete de uma vez;
 * consertar aqui seria consertar na tela errada.
 *
 * ─── ESCOPO ───
 *
 * Tudo abaixo é `.rc-*` — prefixo NOVO, conferido antes de escolher: zero
 * ocorrências em `estilo.css`, em `robo_telas.css` e em todo `web/static/*.js`.
 * Logo, a conta de colisão de classe do `testes_dos_ajustes.py` (hoje 68) NÃO
 * sobe: ela cruza o que as DUAS folhas definem. Onde uma regra precisa vencer a
 * da casa por especificidade, o gancho é `.robo-raiz.rc-canais`, que só existe
 * nesta tela. Precedente do nome: `prevoo-` nasceu por esta mesma razão.
 */

/* ------------------------------------------- a gaveta "Avançado" -- */
/* VEM ANTES DO `.rc-secao` DE PROPÓSITO, e a ordem é load-bearing: o `border: 0`
   daqui e o `border-top` de lá têm a MESMA especificidade (0,2,0), então quem
   vier depois ganha. Invertido, a gaveta "Avançado" perderia a régua da seção e
   ninguém descobriria por quê.

   O SELETOR FICA GENÉRICO (`.rc-gaveta`) MESMO COM UMA GAVETA SÓ na tela: a
   segunda existiu por uma rodada — os dois prompts de IA — e saiu porque ela
   contrariava instrução escrita do dono com um argumento que a régua desmentiu
   (ver `robo_canais.js`, `blocoDosPrompts`). Se ele decidir recolhê-los, é
   acrescentar a classe e nada aqui muda. */
.robo-raiz .rc-gaveta {
  border: 0; background: transparent; padding: 0; border-radius: 0;
  margin: 6px 0 0;
}
/* `display:flex` no `<summary>` já apaga o triângulo nativo do Chrome; as duas
   linhas seguintes cobrem Safari e Firefox. O marcador volta como TEXTO no
   `::before`, que num contêiner flex é o primeiro item e herda o `gap`. Sem ele
   a linha ficaria idêntica a um título estático e o único jeito de descobrir
   que ela abre seria clicando por acaso — é o mesmo conserto que a gaveta da
   tela Produzir já carrega, com a mesma cor. */
.robo-raiz .rc-gaveta > summary {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  cursor: pointer; list-style: none;
  font-family: var(--mono); font-size: 11px; letter-spacing: .16em;
  text-transform: uppercase; font-weight: 600; color: var(--ink);
}
/* O RESUMO AO LADO DO RÓTULO NÃO HERDA O VERSALETE, e isto foi visto no
   navegador antes de ser escrito: sem esta regra a linha saía
   "OS DOIS PROMPTS DE IA VAZIO = O PROMPT PADRÃO DO AGENTE" — a frase em caixa
   alta espaçada colada no título, lida como se fosse o nome da gaveta. É o
   mesmo conserto que o `.grp .c` desta folha já carrega, e pela mesma razão
   escrita lá: frase em caixa alta se lê como continuação do rótulo. O `.c`
   dentro de um `<summary>` não é alcançado por aquela regra porque a gaveta não
   é um `.grp`. */
.robo-raiz .rc-gaveta > summary .c {
  font-family: var(--sans); font-size: 12px; font-weight: 400;
  letter-spacing: 0; text-transform: none; color: var(--dim);
}
.robo-raiz .rc-gaveta > summary::-webkit-details-marker { display: none; }
.robo-raiz .rc-gaveta > summary::before {
  content: "\25B8"; color: var(--red); font-size: 11px; line-height: 1;
}
.robo-raiz .rc-gaveta[open] > summary::before { content: "\25BE"; }
.robo-raiz .rc-gaveta > summary:focus-visible {
  outline: 2px solid var(--red); outline-offset: 3px;
}
.robo-raiz .rc-gaveta[open] > summary { margin-bottom: 16px; }
/* A última linha da gaveta não precisa do respiro que separa linhas IRMÃS: logo
   embaixo já vem a régua da seção seguinte. Somados dariam 52px de vazio. */
.robo-raiz .rc-gaveta .row:last-child { margin-bottom: 0; }

/* -------------------------------------------- a marca de seção (`.grp`) -- */
/* ESTRUTURAL SÓ — a tipografia fica na regra `.grp.rc-secao` logo abaixo,
   porque este mesmo gancho serve a um `<div>` de cabeçalho E a um `<details>`,
   e num `<details>` quem carrega a tipografia é o `<summary>`.

   `position:absolute` no tique, e não um item flex: o `.grp` é `display:flex`
   com `gap:10px`, então um filho de verdade empurraria o rótulo e desalinharia
   o `.c` ao lado. Fora do fluxo, o tique não custa uma unidade de layout. */
.robo-raiz .rc-secao {
  position: relative;
  border-top: 1px solid var(--line);
  padding-top: 15px;
  margin: 34px 0 14px;
}
.robo-raiz .rc-secao::before {
  content: ""; position: absolute; top: -1px; left: 0;
  width: 34px; height: 2px; background: var(--red);
}
/* O RESPIRO ENTRE GRUPOS É MAIOR QUE ENTRE CAMPOS, E ISSO É A REGRA — 34px de
   margem contra os 18px do `.row`, quase o dobro, mais a régua. Era isso que
   faltava para as seções se lerem como seções: com 14px em toda parte, quinze
   controles chegam como uma lista. */

/* A PRIMEIRA SEÇÃO NÃO LEVA RÉGUA. Ela nasce a 18px da borda do cartão, e uma
   régua ali seriam duas linhas paralelas quase encostadas — lê-se como moldura
   torta, não como separação. Sobra o tique sozinho, que é a abertura do
   formulário e o primeiro vermelho que o olho encontra. */
.robo-raiz .rc-secao.rc-topo {
  border-top: 0; padding-top: 6px; margin-top: 0;
}
.robo-raiz .rc-secao.rc-topo::before { top: 0; }

/* Estrutura das três abas de Canais. A aparência final vive no acabamento
   Linhas; aqui fica o contrato seguro que continua válido se o tema falhar ou
   for trocado. */
.robo-raiz .rc-editor-workspace { min-width: 0; }
.robo-raiz .rc-editor-tabs { display: flex; overflow-x: auto; }
.robo-raiz .rc-editor-panels { min-width: 0; }
.robo-raiz .rc-editor-panel[hidden] { display: none !important; }

/* A TIPOGRAFIA DO CABEÇALHO — um degrau ACIMA do rótulo de campo, que é o que
   faltava para existir hierarquia: os dois eram mono, versalete e `--dim`, e a
   diferença entre "título de grupo" e "nome de campo" era meio pixel.
       rótulo de campo   mono 10.5px  .13em  --ink   400
       título de seção   mono 11px    .16em  --ink   600     <- este
   `.grp.rc-secao` = (0,3,0) e vence a `.robo-raiz .grp` (0,2,0) sem depender da
   ordem das linhas. */
.robo-raiz .grp.rc-secao {
  font-size: 11px; letter-spacing: .16em; color: var(--ink); font-weight: 600;
}

/* O RÓTULO SOBE PARA `--ink`, E ISSO CONSERTA UM DEGRAU QUE EU MESMO ACHATEI.
   Antes desta rodada havia dois níveis de cinza: rótulo em `--dim` e ajuda em
   `--faint`. Ao subir a ajuda para `--dim` (logo abaixo, e por um piso de
   contraste que não era negociável), os DOIS passaram a ter a mesma tinta — e
   como a ajuda é maior (12px contra 10,5px), ela ficou visualmente mais pesada
   que o rótulo do campo que ela explica. Hierarquia invertida.
   Recuperar por baixo não dava (a ajuda tem de passar em 4,5:1), então o degrau
   volta por cima: o rótulo é curto, versalete e é ele que NOMEIA o controle.
   Ele não colide com o título de seção — a distância ali é peso (600 contra
   400), tamanho e espacejamento, não cor. */
.robo-raiz.rc-canais .campo-ajuste > label { color: var(--ink); }
/* O resumo ao lado sobe de `--faint` (2,9:1 sobre o cartão) para `--dim`
   (5,7:1). Ele diz o que a seção decide; em 2,9:1 ele existia só no HTML. */
.robo-raiz .rc-secao .c { color: var(--dim); font-size: 12px; }

/* ----------------------------------------------- o cinza que era demais -- */
/* **A MEDIDA QUE MOTIVOU A REGRA:** este formulário tem 16 blocos de ajuda
   somando ~1.500 caracteres, TODOS em `--faint` — que dá **2,91:1** sobre o
   cartão (`--surf`), abaixo do piso de 4,5:1 de texto normal e abaixo até do
   3:1 de texto grande, a 12px. Não é impressão: é a maior área de texto da tela
   pintada com a tinta menos legível dela. `--dim` sobre o mesmo fundo dá
   **5,66:1** e continua claramente subordinado ao `--ink` (15:1) dos campos —
   ou seja, sobe o piso sem achatar a hierarquia.

   `.robo-raiz.rc-canais` = (0,3,0) e vence a `.robo-raiz .dica` (0,2,0). O
   gancho de tela existe exatamente para isto: as outras seis telas do Robô
   ficam byte a byte como estão. */
.robo-raiz.rc-canais .dica { color: var(--dim); }

/* O PLACEHOLDER ERA O RESTO DO MESMO CINZA, E EU TINHA PARADO NA `.dica`.
   Contados na tela renderizada depois da primeira passada: **13 placeholders,
   496 caracteres, todos ainda em `--faint` = 2,91:1** — exatamente o número que
   motivou a regra de cima. E no formulário de criar VAZIO, que é o estado do
   print do dono, o texto de dentro de todo campo é justamente esse.

   O que decide é o CONTEÚDO deles, não a área: **oito dos treze não são
   exemplo, são a regra do campo** — "vazio = a voz global (Ajustes)", "vazio =
   o volume padrão do robô", "vazio = o prompt padrão do gerador de imagens".
   Ou seja, a informação que decide o que fazer com o campo estava pintada com a
   tinta menos legível dele. `--dim` os põe no mesmo piso da ajuda (5,66:1) e
   eles continuam bem abaixo do valor digitado, que é `--ink` (15:1) — que é a
   distinção que um placeholder precisa manter: "isto ainda não é o seu texto".

   Os três seletores repetem os da regra da casa (l. 365-367) de propósito: ela
   é (0,2,0) e casa `.fld` e os dois campos, e cobrir menos deixaria um pedaço
   do formulário no cinza velho — que foi como este defeito sobreviveu à
   primeira passada. */
.robo-raiz.rc-canais .fld::placeholder,
.robo-raiz.rc-canais .campo-ajuste input::placeholder,
.robo-raiz.rc-canais .campo-ajuste textarea::placeholder { color: var(--dim); }

/* A consulta da voz fica junto ao campo, com ícone e texto; sem depender da cor. */
.robo-raiz.rc-canais .rc-voz-estado {
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px;
  color: var(--dim); font-size: .875rem; line-height: 1.5; min-width: 0;
}
.robo-raiz.rc-canais .rc-voz-estado[hidden],
.robo-raiz.rc-canais .rc-voz-estado [hidden] { display: none; }
.robo-raiz.rc-canais .rc-voz-estado > [role="status"] {
  display: flex; align-items: flex-start; gap: 6px; min-width: 0; flex: 1 1 240px;
}
.robo-raiz.rc-canais .rc-voz-mensagem { overflow-wrap: anywhere; }
.robo-raiz.rc-canais .rc-voz-icone { display: flex; flex: 0 0 16px; padding-top: 2px; }
.robo-raiz.rc-canais .rc-voz-icone svg { width: 16px; height: 16px; }
.robo-raiz.rc-canais .rc-voz-estado[data-estado="encontrada"] { color: var(--ok); }
.robo-raiz.rc-canais .rc-voz-estado[data-estado="nao_encontrada"],
.robo-raiz.rc-canais .rc-voz-estado[data-estado="invalida"] { color: var(--bad); }
.robo-raiz.rc-canais .rc-voz-estado[data-estado="indisponivel"],
.robo-raiz.rc-canais .rc-voz-estado[data-estado="sem_chaves"] { color: var(--warn); }
.robo-raiz.rc-canais .campo-ajuste input[aria-invalid="true"] { border-color: var(--bad); }
.robo-raiz.rc-canais .rc-voz-tentar,
.robo-raiz.rc-canais .rc-voz-integracoes {
  min-height: 44px; padding: 6px 0; display: inline-flex; align-items: center;
  font: inherit; color: var(--ink); background: transparent; border: 0;
  text-decoration: underline; text-underline-offset: 3px; cursor: pointer;
}
.robo-raiz.rc-canais .rc-voz-tentar:hover,
.robo-raiz.rc-canais .rc-voz-integracoes:hover { color: var(--texto); }
.robo-raiz.rc-canais .rc-voz-tentar:focus-visible,
.robo-raiz.rc-canais .rc-voz-integracoes:focus-visible { outline: 2px solid var(--red); outline-offset: 4px; }

/* A FRASE DE SEÇÃO — as duas mais compridas da tela (198 e 324 caracteres) e as
   duas que mais importam ("nenhuma etapa do robô lê isto ainda"). Elas falam da
   SEÇÃO, não de um campo, então ganham medida própria: `70ch` é o limite em que
   o olho ainda acha o começo da linha seguinte, e num monitor de 1240px sem
   isso elas atravessavam a coluna inteira. */
.robo-raiz .rc-nota {
  font-size: 12.5px; line-height: 1.6; max-width: 70ch; margin: 10px 0 18px;
}

/* --------------------------------------------- a oferta da nossa faixa -- */
/* Um degrau acima do cartão (`--surf2`), como o `.aviso` desta mesma folha. É o
   único bloco da seção que a casa OFERECE em vez de perguntar, e sem caixa
   nenhuma ele se lia como mais um parágrafo de ajuda com dois botões soltos. */
.robo-raiz .rc-faixa {
  background: var(--surf2); border: 1px solid var(--line);
  border-radius: var(--r); padding: 12px 13px; margin-bottom: 18px;
}
.robo-raiz .rc-faixa .rc-ficha { margin: 0; }
/* Dentro da caixa o recado é o ÚLTIMO elemento; o `margin-bottom:18px` que o
   `.aviso` traz abriria um vão embaixo dele. */
.robo-raiz .rc-faixa .aviso { margin: 10px 0 0; }

/* O LINK DA LICENÇA — E ESTA CAIXA O TINHA REBAIXADO, NO PONTO EXATO EM QUE EU
   DIZIA ESTAR PROMOVENDO ELE.
   Medido: solto sobre `--surf` o vermelho da marca dá **4,01:1**; dentro da
   `.rc-faixa`, cujo fundo é `--surf2`, cai para **3,70:1** — e ele é 12px em
   peso 400, ou seja texto normal, ou seja piso de 4,5:1. A caixa nasceu para
   dar peso à oferta e o único efeito medível dela sobre a licença foi tornar a
   licença menos legível. Isso não é troca aceitável: a licença é o fato que
   custou nove vídeos publicados sob CC BY-NC.
   `--ink` (15:1 aqui) com sublinhado resolve sem inventar cor nenhuma, e o
   sublinhado é o que mantém a leitura de LINK depois de o vermelho sair —
   trocar a cor sem ele deixaria a frase inteira parecendo texto corrido. O
   vermelho da tela não se perde: ele continua nos tiques, no triângulo da
   gaveta, no foco e no botão principal, que é onde a regra deste bloco o quer.
   **O SELETOR É `.rc-ficha a`, E NÃO `.rc-faixa a` — a primeira versão desta
   regra SUBLINHOU UM BOTÃO.** "Baixar a música" é um `<a class="btn sec
   pequeno">` e mora dentro da mesma caixa; um botão sublinhado se lê como link
   quebrado. Só apareceu ao renderizar — no CSS as duas formas parecem a mesma
   coisa. Ancorar na FICHA (o parágrafo de texto) em vez de na caixa é o que
   separa "link dentro de uma frase" de "controle com cara de botão". */
.robo-raiz .rc-ficha a { color: var(--ink); text-decoration: underline; }
.robo-raiz .rc-ficha a:focus-visible {
  outline: 2px solid var(--red); outline-offset: 2px;
}

/* O CAMPO DE ENDEREÇO NUNCA FOI PINTADO PELA CASA — e isso só apareceu quando
   fui medir o contraste do placeholder dele. A regra de campo desta folha
   (l. 350-364) lista `input[type="text"]` e `input[type="number"]`, e o endereço
   da música é `type="url"`: ele caía no desenho PADRÃO DO NAVEGADOR, com fundo
   `rgb(59,59,59)` em vez de `--surf`. Consequência medida: mesmo com a regra de
   placeholder acima, o dele ficava em **3,45:1** — abaixo do piso — porque o
   fundo era outro. Era o único campo do formulário fora da paleta, no meio da
   seção que esta rodada mexeu.
   Escopado em `.rc-canais` como o resto do bloco: `type="url"` também aparece
   noutras telas do Robô, e pintá-las daqui seria repintar tela que outra frente
   está editando. A correção geral pertence à regra da casa e está declarada no
   relatório para quem é dono dela. */
.robo-raiz.rc-canais .campo-ajuste input[type="url"] {
  width: 100%; background: var(--surf); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--r);
  padding: 9px 11px; font-family: inherit; font-size: 14px;
}
.robo-raiz.rc-canais .campo-ajuste input[type="url"]::placeholder {
  color: var(--dim);
}

/* ------------------------------------------------------- linha de ações -- */
.robo-raiz .rc-acoes {
  display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-top: 8px;
}

/* --------------------------- o `pequeno()` que não encolhia nada -- */
/* DEFEITO REAL, e ele explica metade da queixa de "não tem hierarquia".
   `shell.js:517` só acrescenta a classe; quem a pinta é `estilo.css:861`
   (`.btn.pequeno`, especificidade **0,2,0**). Esta folha declara
   `.robo-raiz .btn { padding:10px 18px; font-size:13.5px }` — também **0,2,0** —
   e é INJETADA em `document.head` em tempo de execução, ou seja vem depois do
   `<link>` e ganha o empate. Resultado, lido na árvore: os cinco botões
   secundários desta tela (os dois "Baixar .txt", "Baixar a música", "Usar a
   nossa música" e "Escolher arquivo") saíam com a MESMA massa do "Criar canal",
   e a única diferença entre a ação principal e as cinco de apoio era a cor.
   Tirando a cor, não sobrava hierarquia nenhuma — que é exatamente o que o dono
   descreveu.

   (0,4,0) resolve sem `!important` e sem depender de ordem de carregamento.
   Escopado na tela porque a medição é DESTA tela: as outras seis herdam o mesmo
   empate, mas quem for consertá-las tem de olhar os botões delas primeiro. */
.robo-raiz.rc-canais .btn.pequeno {
  padding: 6px 12px; font-size: 12px; border-radius: 6px;
}
/* ===== fim FRENTE canais ===== */

/* O BLOCO DA ENTREGA respira: ele separa o cabecalho do log e carrega tres
   coisas (caminho, ficha, placar) que sao a resposta do video pronto. */
.robo-raiz .rb-entrega { display: flex; flex-direction: column; gap: 10px;
  margin: 18px 0; }
.robo-raiz .rb-entrega:empty { display: none; margin: 0; }
.robo-raiz .rb-entrega .btn { align-self: flex-start; }

/* --------------------------- A ENTREGA, COMO NO MOCKUP ---------------------
   A primeira versao ficou largura cheia, com blocos soltos separados por fios,
   e o dono comparou com o mockup: "ta completamente diferente". Estava -- o
   mockup e um CARTAO de duas colunas, e isso nao e acabamento: e a forma que
   torna a tela um instrumento em vez de uma pagina de texto. */
.robo-raiz .rp-entrega-cartao {
  display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  gap: 22px; border: 1px solid var(--line); background: var(--surf);
  border-radius: var(--r); padding: 18px;
}
@media (max-width: 760px) {
  .robo-raiz .rp-entrega-cartao { grid-template-columns: 1fr; }
}
.robo-raiz .rp-entrega-lado { display: flex; flex-direction: column; gap: 10px; }

/* A COLUNA DO PLAYER carrega o MOTIVO de ele nao existir. Buraco sem
   explicacao se le como tela quebrada, e o player depende de uma rota no
   agente que ainda nao foi escrita. */
.robo-raiz .rp-sem-player {
  aspect-ratio: 16 / 9; border: 1px dashed var(--line); border-radius: var(--r);
  background: var(--ground); display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 8px; text-align: center;
  padding: 20px;
}
.robo-raiz .rp-sem-player b { color: var(--ink); font-size: 14px; font-weight: 620; }
.robo-raiz .rp-sem-player span { color: var(--faint); font-size: 12.5px; max-width: 34ch; }

.robo-raiz .rp-entrega-botoes { display: flex; gap: 9px; flex-wrap: wrap; }

/* A FICHA E GRADE ROTULADA: rotulo miudo em cima, valor em mono embaixo.
   "125 MB - sha256 a1d9..." obriga a ler para saber o que e cada pedaco. */
.robo-raiz .rp-ficha {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(84px, 1fr));
  gap: 12px; margin-top: 4px;
}
.robo-raiz .rp-ficha > div {
  font-family: var(--mono); font-size: 12px; color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.robo-raiz .rp-ficha span {
  display: block; font-size: 9.5px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--faint); margin-bottom: 3px;
}

/* O TITULO DO PLACAR E A META na mesma linha: valor sem alvo e informativo,
   com alvo e veredito. A distancia vai junto porque "20 %" sozinho nao diz se
   e bom. */
.robo-raiz .rp-placar-topo {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 16px; flex-wrap: wrap; margin-bottom: 14px;
}
.robo-raiz .rp-placar-rot {
  font-family: var(--mono); font-size: 10px; letter-spacing: .2em;
  text-transform: uppercase; color: var(--faint);
}
.robo-raiz .rp-meta { font-family: var(--mono); font-size: 11.5px; color: var(--dim); }
.robo-raiz .rp-meta b { color: var(--warn); font-weight: 500; }
.robo-raiz .rp-meta b.ok { color: var(--ok); }

/* A MINIATURA ocupa a moldura inteira, no lugar do texto de espera. Mesma
   proporcao do `rp-sem-player` para a troca nao pular a pagina. */
.robo-raiz .rp-miniatura-caixa {
  aspect-ratio: 16 / 9; border: 1px solid var(--line); border-radius: var(--r);
  background: var(--ground); overflow: hidden;
}
.robo-raiz .rp-miniatura { width: 100%; height: 100%; object-fit: cover; display: block; }

/* O PLAY POR CIMA DA MINIATURA. Sem ele a imagem se le como IMAGEM e nao como
   video -- o circulo e o que diz "isto abre". */
.robo-raiz .rp-miniatura-caixa { position: relative; }
.robo-raiz .rp-play {
  position: absolute; inset: 0; margin: auto; width: 62px; height: 62px;
  border-radius: 50%; border: 1px solid rgba(255,255,255,.28);
  background: rgba(0,0,0,.45); cursor: pointer; padding: 0;
  display: flex; align-items: center; justify-content: center;
  backdrop-filter: blur(2px);
}
.robo-raiz .rp-play::after {
  content: ''; border-left: 16px solid #fff; margin-left: 4px;
  border-top: 10px solid transparent; border-bottom: 10px solid transparent;
}
.robo-raiz .rp-play:hover { background: rgba(0,0,0,.62); border-color: #fff; }
.robo-raiz .rp-play:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }

/* A SEGUNDA FILEIRA de botoes e' a utilitaria: mesma largura, menos peso. */
.robo-raiz .rp-entrega-botoes.secundarios { margin-top: -2px; }

/* O SHA nao e' dado de relance -- ele existe para colar num suporte. */
.robo-raiz .rp-sha {
  font-family: var(--mono); font-size: 10.5px; color: var(--faint);
  margin-top: 2px; word-break: break-all;
}

/* ══ O CAMPO DE PORCENTAGEM MOSTRA A UNIDADE ═══════════════════════════════
 *
 * Dono, olhando a tela de canais: *"aqui deveria ser % e não vezes"*. O campo
 * já era percentual por dentro; o que faltava era a tela dizer isso. Um `0`
 * sozinho numa caixa, com um rótulo que dizia "quantas", lê-se como CONTAGEM
 * DE VEZES — e essa leitura não escala: 10 aparições num vídeo de 3 min e num
 * de 20 min são coisas diferentes.
 *
 * O `%` é um `::after` do EMBRULHO, e não do `<input>`: campo de formulário é
 * elemento vazio e não aceita pseudo-elemento. Escrever `.pct-entrada::after`
 * não pinta nada e não avisa — foi a primeira tentativa.
 *
 * `pointer-events: none` para o clique no símbolo cair no campo, e não no
 * nada. Sem isso quem clica em cima do `%` não consegue digitar, e o defeito
 * parece "o campo travou".
 */
.robo-raiz .pct-campo { position: relative; }
.robo-raiz .pct-campo::after {
  content: '%';
  position: absolute; right: 11px; top: 50%; transform: translateY(-50%);
  color: var(--dim); font-size: 13px; pointer-events: none;
}
/* AS SETINHAS SAEM, e é por causa do `%`: o spinner do Chrome mora no canto
 * direito e cairia exatamente em cima do símbolo. Entre perder as setas e
 * perder a unidade, a unidade vale mais — ela é o que estava faltando. O
 * teclado continua funcionando (seta pra cima/baixo em `type=number`). */
.robo-raiz .pct-entrada { padding-right: 28px; -moz-appearance: textfield; }
.robo-raiz .pct-entrada::-webkit-outer-spin-button,
.robo-raiz .pct-entrada::-webkit-inner-spin-button {
  -webkit-appearance: none; margin: 0;
}


/* ══ A FILEIRA DOS PRESETS ═══════════════════════════════════════════════
 *
 * Ela vive dentro de um `.campo`, e ali `select` e `input[type=text]` são
 * `width:100%` (linha 400) — sem estas regras os quatro controles empilhariam
 * um por linha, ocupando meia tela para escolher uma receita.
 *
 * `flex-wrap` em vez de largura fixa: os nomes dos presets são do aluno e
 * podem ser curtos ou longos, então a fileira tem de saber quebrar sozinha. */
.robo-raiz .rb-presets {
  display: flex; gap: 10px; flex-wrap: wrap; align-items: center;
}
.robo-raiz .rb-presets select.sel { width: auto; flex: 1 1 220px; min-width: 170px; }
.robo-raiz .rb-presets input[type="text"] { width: auto; flex: 1 1 190px; min-width: 150px; }
.robo-raiz .rb-presets .btn { flex: 0 0 auto; }
/* A MESMA ARMADILHA DO CARTÃO DE OPÇÃO, e eu deixei passar aqui.
 *
 * `.campo label` (estilo.css:191) pinta este `<label>` de rótulo — mono, caixa
 * alta, cinza —, então a caixa saía escrita "USAR SEMPRE NESTE CANAL", que se
 * lê como cabeçalho e não como algo clicável. Consertei os rádios logo abaixo
 * e deixei o defeito UMA LINHA ACIMA; foi a captura da tela publicada que
 * mostrou, não o teste.
 *
 * É o terceiro lugar com o mesmo remédio (`.rb-marca`, `.opcao-cartao`, este):
 * quem escrever o quarto label dentro de `.campo` vai precisar dele de novo. */
.robo-raiz label.rb-preset-padrao {
  display: flex; align-items: center; gap: 7px; white-space: nowrap; margin: 0;
  font-family: inherit; font-size: 13px; letter-spacing: normal;
  text-transform: none; color: var(--ink); cursor: pointer;
}
.robo-raiz label.rb-preset-padrao input[type="checkbox"] { width: auto; margin: 0; }

/* Na tela estreita cada controle pega a linha inteira — o mesmo corte de 820px
 * que a grade de Produzir já usa. */
@media (max-width: 820px) {
  .robo-raiz .rb-presets > * { flex: 1 1 100%; }
}


/* ══ O CARTÃO DE OPÇÃO DENTRO DE UM `.campo` ═════════════════════════════
 *
 * `.campo label` (estilo.css:191) alcança QUALQUER label descendente e o pinta
 * de rótulo: mono, caixa alta, cinza, `display:block`. Foi o que transformou
 * as duas opções de narração em dois cabeçalhos com o botão solto na direita.
 *
 * O `.rb-marca` já desfaz isso para a caixa de seleção, e o comentário dele
 * (estilo.css:1848) descreve o mesmo defeito — este bloco é o remédio
 * equivalente para o cartão. Sem ele, reusar `.opcao-cartao` aqui herdaria a
 * tipografia de rótulo e o cartão sairia em caixa alta.
 *
 * As duas lado a lado, e não empilhadas: são a MESMA pergunta com duas
 * respostas, e ver as duas juntas é o que deixa a escolha óbvia. */
.robo-raiz .campo .opcoes-cartao { flex-direction: row; flex-wrap: wrap; gap: 10px; }
.robo-raiz .campo .opcoes-cartao > .opcao-cartao { flex: 1 1 250px; }
.robo-raiz .campo label.opcao-cartao,
.robo-raiz .campo label.opcao-cartao b,
.robo-raiz .campo label.opcao-cartao small {
  font-family: inherit; letter-spacing: normal; text-transform: none;
}
.robo-raiz .campo label.opcao-cartao {
  display: flex; margin: 0; color: var(--ink); font-size: 14px;
}
.robo-raiz .campo label.opcao-cartao small { color: var(--dim); }
.robo-raiz .campo label.opcao-cartao input { width: auto; margin-top: 3px; }

/* Na tela estreita cada opção pega a linha inteira — o mesmo corte de 820px da
 * grade de Produzir. */
@media (max-width: 820px) {
  .robo-raiz .campo .opcoes-cartao > .opcao-cartao { flex: 1 1 100%; }
}


/* O SELETOR DE "QUANTOS AO MESMO TEMPO", na linha de cada máquina.
 *
 * Ele fica entre o nome e o chip de estado, e não numa terceira linha: é uma
 * propriedade DA máquina, e empurrá-lo para baixo o desligaria visualmente do
 * item a que pertence quando há mais de uma na lista.
 *
 * `text-transform: none` no rótulo pelo mesmo motivo da caixa "usar sempre"
 * (2026-08-21): a regra de caixa alta dos rótulos desta casa vale para
 * cabeçalho de campo, e aplicada a uma frase curta em minúsculas ela grita. */
.rb-maq-campo {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: var(--tinta-fraca, #6b7280);
  text-transform: none;
  white-space: nowrap;
}
.rb-maq-quantas {
  font-size: 12px;
  padding: 4px 6px;
  border-radius: 6px;
  border: 1px solid var(--borda, #d1d5db);
  background: var(--fundo, #fff);
  color: inherit;
}
.rb-maq-quantas:disabled { opacity: .6; }

/* A TABELA DE CENAS DENTRO DA GAVETA DE ATIVIDADE.
 *
 * `.pw-scene-details` e `.pw-scene-table-wrap` já vêm da folha aprovada
 * (production-workspace.css:316-318) — ela desenha a moldura e a rolagem
 * horizontal, e para nisso: a tabela em si nunca teve emissor, então nunca
 * precisou de célula. Estas quatro regras são só o mínimo para as colunas se
 * lerem, e ficam AQUI porque a folha aprovada é idêntica à do simulador e
 * mexer nela desalinharia os dois lados. */
.pw-scene-table-wrap table { width: 100%; border-collapse: collapse; font-size: 12px; }
.pw-scene-table-wrap th {
  padding: 6px 12px 6px 0;
  color: var(--pw-muted-2, #737b89);
  font-weight: 650;
  text-align: left;
  white-space: nowrap;
}
.pw-scene-table-wrap td {
  padding: 7px 12px 7px 0;
  border-top: 1px solid var(--pw-line-soft, #20232b);
  color: #d3d6dc;
  line-height: 1.45;
  vertical-align: top;
}
/* O número da cena alinha por dígito, e o "sem base" da gaveta é uma frase de
 * apoio — não pode competir com o log ao lado. */
.pw-scene-table-wrap td:first-child { color: var(--pw-muted, #9ca3b0); font-variant-numeric: tabular-nums; }
.pw-scene-note { margin: 0; color: var(--pw-muted, #9ca3b0); font-size: 12px; line-height: 1.55; }

/* A LINHA DE PROGRESSO DA FILA NÃO PODE EMPURRAR A PORCENTAGEM PARA FORA.
 *
 * `.pw-progress-copy` é um flex com `space-between`, e o nome da etapa vem do
 * agente — string livre, que inventa nome de fase o tempo todo. Numa coluna de
 * 350px uma fase comprida esticaria o `<span>` e o `%` sumiria da direita. O
 * corte é só no item da fila; no detalhe, que é largo, a frase cabe inteira. */
.pw-queue-item .pw-progress-copy > span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.pw-queue-item .pw-progress-copy > strong { flex: 0 0 auto; }

/* O RELOGIO DA PRODUCAO, no cabecalho do detalhe.
   Vive acima da barra de progresso e responde "ha quanto tempo" ao lado do
   "quanto falta". O tratamento e o `technical` do DESIGN.md — Geist Mono, 12px,
   letter-spacing .08em — que a folha reserva justamente para procedencia,
   sequencia e MEDIDA. Nao e um badge colorido: aqui a cor esta reservada a
   acao, selecao e progresso, e um relogio nao e nenhum dos tres.
   `tabular-nums` porque o numero anda a cada 3s: sem largura fixa de digito o
   valor tremeria de leve a cada repintura, e tremor num numero que so cresce
   le-se como defeito.
   Escrito aqui, e nao no production-workspace.css, porque aquele arquivo e o
   espelho do simulador — o que e nosso fica na nossa folha. */
.pw-elapsed {
  margin-bottom: 7px;
  display: flex;
  align-items: baseline;
  justify-content: flex-end;
  gap: 8px;
}
.pw-elapsed > i {
  color: var(--pw-muted-2, #737b89);
  font: 500 12px/1 var(--mono), monospace;
  font-style: normal;
  letter-spacing: .08em;
  text-transform: uppercase;
}
.pw-elapsed > strong {
  color: var(--pw-text, #f3f4f6);
  font: 600 15px/1 var(--mono), monospace;
  font-variant-numeric: tabular-nums;
}

/* O CORTE E DE CONTAINER, NAO DE VIEWPORT — e a diferenca importa aqui.
   A folha aprovada declara `container: pw-page` e `container: pw-detail` e faz
   TODOS os cortes com `@container`, porque o que decide o layout do detalhe e a
   largura da COLUNA dele, nao a da janela: com o trilho, a barra contextual e a
   fila ocupando ~650px, o detalhe empilha mesmo numa tela de 1386px.
   Escrevi isto como `@media` na primeira versao e o resultado foi o relogio
   alinhado a direita sobre uma barra de largura cheia — o corte nunca disparava
   porque a JANELA era larga. O numero 760 e o mesmo em que
   `.pw-detail-title-row` vira coluna (production-workspace.css:480), para o
   relogio e o titulo mudarem de eixo no mesmo instante. */
@container pw-detail (max-width: 760px) {
  .pw-elapsed { justify-content: flex-start; }
}

/* O EXCLUIR DA LINHA GANHA BORDA — pedido explicito do dono.
   DIVERGENCIA DECLARADA: o simulador usa `pw-button-quiet-danger` aqui
   (production-workspace.tsx:900), ou seja sem borda e sem fundo, e a nossa
   copia fazia igual. O dono olhou a tela e pediu borda: numa linha com "Abrir"
   e "Assistir" emoldurados, um terceiro item que e so texto vermelho nao le
   como botao — parece um link solto no fim da fileira.

   So a BORDA entra. Nao uso `pw-button-danger` inteiro (que traz fundo
   avermelhado) porque tres botoes lado a lado com um bloco vermelho fariam a
   acao destrutiva competir com a principal — e a regra da casa e que uma regiao
   tem UMA acao primaria clara. Borda no tom de perigo, fundo transparente,
   texto vermelho: vira botao sem virar alarme.
   O hover ja e coberto pela regra que production-workspace.css:69 aplica aos
   dois danger, entao ele continua acendendo igual. */
.pw-row-actions .pw-button-quiet-danger {
  border-color: rgb(var(--danger-rgb, 180 35 24) / .45);
}

/* A BARRA DO PASSO, no fim do trilho de etapas.
   Responde "quanto falta DENTRO da etapa atual" — no encoder, quantos beats já
   saíram. É o contador que o agente 0.1.84 passou a publicar (`passo`), e que
   o Acompanhar antigo já mostrava na régua de fases; a bancada nova nasceu sem.
   Reusa `.pw-progress` de propósito: é a mesma forma da barra do cabeçalho, e
   duas barras com desenhos diferentes na mesma tela leriam como duas coisas
   sem relação. O filete separando deixa claro que ela pertence ao trilho, e
   não ao bloco seguinte. */
.robo-raiz .pw-phases .pw-phase-step {
  margin-top: 16px;
  padding-top: 15px;
  border-top: 1px solid var(--pw-line, #292d37);
}
.robo-raiz .pw-phases .pw-phase-step .pw-progress-copy > span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Tabular porque o par anda a cada 3s: sem largura fixa de dígito o "30 / 269"
   tremeria de leve a cada repintura. */
.robo-raiz .pw-phases .pw-phase-step .pw-progress-copy > strong {
  flex: 0 0 auto;
  font-variant-numeric: tabular-nums;
}

/* O segundo rotulo do chip do cabecalho ganha respiro a esquerda, para
   "Tempo 30min 12s" e "Etapa 58 / 269" nao colarem num par so. */
.robo-raiz .pw-elapsed > .pw-elapsed-sep { margin-left: 10px; }

/* Acompanhamento: a posição do marcador acompanha a etapa confirmada.
   Só a órbita do trabalho em andamento repete; pausa, estado terminal e
   movimento reduzido mantêm o mesmo ponto da trilha, sem deslocamento animado.
   O orçamento visual é uma translação entre etapas e uma órbita de 54px. */
.pw-tracking {
  --tracking-active: var(--pw-red, #ff4545);
  --tracking-surface: var(--pw-surface, #111319);
  --tracking-line: var(--pw-line, #292d37);
  --tracking-muted: var(--pw-muted, #9ca3b0);
  min-width: 0;
  max-width: 100%;
  padding: 4px 0 0;
  color: var(--pw-text, #f3f4f6);
  font-family: Geist, Arial, sans-serif;
  font-size: 14px;
  line-height: 1.5;
}

.pw-tracking *,
.pw-tracking *::before,
.pw-tracking *::after {
  box-sizing: border-box;
}

.pw-tracking .pw-tracking-heading {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 20px 28px;
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.pw-tracking .pw-tracking-heading > div {
  flex: 1 1 auto;
  min-width: 0;
}

.pw-tracking .pw-tracking-title {
  margin: 0;
  color: var(--pw-text, #f3f4f6);
  font: 650 28px/1.2 Geist, Arial, sans-serif;
  letter-spacing: -.025em;
  overflow-wrap: anywhere;
}

.pw-tracking .pw-tracking-description {
  max-width: 65ch;
  margin: 10px 0 0;
  color: var(--tracking-muted);
  font-size: 14px;
  line-height: 1.65;
  overflow-wrap: anywhere;
}

.pw-tracking .pw-tracking-route {
  position: relative;
  isolation: isolate;
  min-width: 0;
  margin: 28px 0 24px;
  padding: 0;
}

.pw-tracking .pw-tracking-stages {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  align-items: stretch;
  gap: 0;
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
  list-style: none;
}

.pw-tracking .pw-tracking-stages > li {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: 36px auto;
  align-content: start;
  justify-items: center;
  gap: 14px;
  min-width: 0;
  margin: 0;
  padding: 14px 6px 18px;
  border: 0;
  background: none;
  text-align: center;
}

.pw-tracking .pw-tracking-stages > li:not(:last-child)::after {
  position: absolute;
  z-index: -1;
  top: 32px;
  right: -50%;
  left: 50%;
  height: 1px;
  background: var(--tracking-line);
  content: "";
}

.pw-tracking .pw-tracking-stages > li.is-complete::after {
  background: #505864;
}

.pw-tracking .pw-tracking-node {
  position: relative;
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  margin: 0;
  border: 1px solid #444c58;
  border-radius: 50%;
  background: var(--tracking-surface);
  color: var(--tracking-muted);
  font: 550 13px/1 Geist, Arial, sans-serif;
  font-variant-numeric: tabular-nums;
}

.pw-tracking .pw-tracking-node svg {
  display: block;
  width: 16px;
  height: 16px;
  stroke-width: 1.8;
}

.pw-tracking .pw-tracking-stages > li > div {
  display: grid;
  align-content: start;
  gap: 5px;
  min-width: 0;
}

.pw-tracking .pw-tracking-stages strong {
  color: #c0c6d0;
  font: 550 14px/1.4 Geist, Arial, sans-serif;
  overflow-wrap: anywhere;
}

.pw-tracking .pw-tracking-stages small {
  display: block;
  color: var(--tracking-muted);
  font: 400 12px/1.5 Geist, Arial, sans-serif;
  overflow-wrap: anywhere;
}

.pw-tracking .pw-tracking-stages > .is-complete .pw-tracking-node {
  border-color: #505864;
  color: var(--pw-green, #54d69b);
}

.pw-tracking .pw-tracking-stages > .is-current .pw-tracking-node {
  border-color: transparent;
  color: var(--pw-text, #f3f4f6);
  font-weight: 650;
}

.pw-tracking .pw-tracking-stages > .is-current strong {
  color: var(--pw-text, #f3f4f6);
  font-weight: 650;
}

.pw-tracking .pw-tracking-stages > .is-current small {
  color: var(--tracking-active);
  font-weight: 550;
}

.pw-tracking .pw-tracking-marker {
  position: absolute;
  z-index: 2;
  top: 0;
  left: 0;
  display: block;
  width: calc(100% / 6);
  height: 64px;
  pointer-events: none;
  transform: translateX(calc(var(--tracking-index, 0) * 100%));
  transition: none;
}

.pw-tracking .pw-tracking-orbit {
  position: absolute;
  top: 5px;
  left: calc(50% - 27px);
  display: block;
  width: 54px;
  height: 54px;
  border: 1px solid var(--tracking-active);
  border-radius: 50%;
  opacity: .72;
  transform-origin: center;
  animation: pw-tracking-orbit-turn 5s linear infinite;
  animation-play-state: paused;
}

.pw-tracking .pw-tracking-orbit > i {
  position: absolute;
  top: -3px;
  left: calc(50% - 2.5px);
  display: block;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--tracking-active);
}

.pw-tracking .pw-tracking-core {
  position: absolute;
  top: 14px;
  left: calc(50% - 18px);
  display: block;
  width: 36px;
  height: 36px;
  border: 1px solid var(--tracking-active);
  border-radius: 50%;
  background: none;
}

.pw-tracking[data-state="running"][data-motion="on"] .pw-tracking-marker {
  transition: transform 450ms cubic-bezier(.16, 1, .3, 1);
}

.pw-tracking[data-state="running"][data-motion="on"] .pw-tracking-orbit {
  animation-play-state: running;
  will-change: transform;
}

.pw-tracking[data-state="pending"],
.pw-tracking[data-state="cancelled"],
.pw-tracking[data-state="unknown"] {
  --tracking-active: #aeb6c2;
}

.pw-tracking[data-state="attention"],
.pw-tracking[data-state="stale"] {
  --tracking-active: var(--pw-amber, #f2bb5e);
}

.pw-tracking[data-state="done"] {
  --tracking-active: var(--pw-green, #54d69b);
}

.pw-tracking[data-state="pending"] .pw-tracking-orbit,
.pw-tracking[data-state="cancelled"] .pw-tracking-orbit,
.pw-tracking[data-state="done"] .pw-tracking-orbit {
  display: none;
}

.pw-tracking[data-state="stale"] .pw-tracking-core,
.pw-tracking[data-state="attention"] .pw-tracking-core {
  border-style: dashed;
}

.pw-tracking .pw-tracking-readout {
  display: flex;
  align-items: flex-start;
  flex-wrap: wrap;
  gap: 20px 40px;
  min-width: 0;
  padding: 20px 0 0;
  border-top: 1px solid var(--tracking-line);
}

.pw-tracking .pw-tracking-readout > div:not(.pw-tracking-step) {
  display: grid;
  align-content: start;
  gap: 6px;
  min-width: 0;
}

.pw-tracking .pw-tracking-readout > div > span {
  color: var(--tracking-muted);
  font-size: 13px;
  line-height: 1.5;
}

.pw-tracking .pw-tracking-readout > div > strong {
  color: var(--pw-text, #f3f4f6);
  font: 600 22px/1.3 Geist, Arial, sans-serif;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.02em;
  overflow-wrap: anywhere;
}

.pw-tracking .pw-tracking-step {
  flex: 1 1 220px;
  min-width: 0;
  max-width: 100%;
  margin: 0;
  padding: 0;
}

.pw-tracking > .pw-tracking-step {
  margin-top: 20px;
}

.pw-tracking .pw-tracking-step .pw-progress {
  width: 100%;
  min-width: 0;
}

.pw-tracking .pw-tracking-step .pw-progress-copy {
  align-items: baseline;
  gap: 12px;
  color: var(--tracking-muted);
  font-size: 13px;
  line-height: 1.5;
}

.pw-tracking .pw-tracking-step .pw-progress-copy > span {
  min-width: 0;
  overflow-wrap: anywhere;
}

.pw-tracking .pw-tracking-step .pw-progress-copy > strong {
  flex: 0 0 auto;
  color: var(--pw-text, #f3f4f6);
  font-size: 14px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.pw-tracking .pw-tracking-step .pw-progress-track {
  height: 4px;
  margin-top: 12px;
  border-radius: 2px;
  background: var(--tracking-line);
}

.pw-tracking .pw-tracking-step .pw-progress-track > span {
  background: var(--tracking-active);
  animation: none;
  transition: none;
}

.pw-tracking .pw-tracking-footnote {
  flex-basis: 100%;
  max-width: 72ch;
  margin: 16px 0 0;
  color: var(--tracking-muted);
  font-size: 13px;
  line-height: 1.65;
  overflow-wrap: anywhere;
}

.pw-tracking .pw-tracking-readout > .pw-tracking-footnote {
  margin: 0;
}

.pw-tracking[data-state="stale"] .pw-tracking-footnote,
.pw-tracking[data-state="attention"] .pw-tracking-footnote {
  color: var(--pw-amber, #f2bb5e);
}

@keyframes pw-tracking-orbit-turn {
  to { transform: rotate(360deg); }
}

@container pw-detail (max-width: 760px) {
  .pw-tracking .pw-tracking-heading {
    flex-wrap: wrap;
    gap: 16px;
  }

  .pw-tracking .pw-tracking-heading > div {
    flex-basis: 100%;
  }
}

@container pw-detail (max-width: 620px) {
  .pw-tracking .pw-tracking-title {
    font-size: 26px;
  }

  .pw-tracking .pw-tracking-route {
    margin: 24px 0;
  }

  .pw-tracking .pw-tracking-stages {
    grid-template-columns: minmax(0, 1fr);
    grid-auto-rows: 76px;
  }

  .pw-tracking .pw-tracking-stages > li {
    grid-template-columns: 60px minmax(0, 1fr);
    grid-template-rows: auto;
    align-content: center;
    align-items: center;
    justify-items: start;
    gap: 0;
    min-height: 76px;
    height: 76px;
    padding: 8px 0;
    text-align: left;
  }

  .pw-tracking .pw-tracking-node {
    justify-self: center;
  }

  .pw-tracking .pw-tracking-stages > li:not(:last-child)::after {
    top: 38px;
    right: auto;
    bottom: -38px;
    left: 30px;
    width: 1px;
    height: auto;
  }

  .pw-tracking .pw-tracking-stages > li > div {
    gap: 4px;
    padding-left: 10px;
  }

  .pw-tracking .pw-tracking-stages strong {
    font-size: 15px;
  }

  .pw-tracking .pw-tracking-stages small {
    font-size: 13px;
  }

  .pw-tracking .pw-tracking-marker {
    width: 60px;
    height: 76px;
    transform: translateY(calc(var(--tracking-index, 0) * 100%));
  }

  .pw-tracking .pw-tracking-orbit {
    top: 11px;
  }

  .pw-tracking .pw-tracking-core {
    top: 20px;
  }

  .pw-tracking .pw-tracking-readout {
    gap: 20px 28px;
  }

  .pw-tracking .pw-tracking-step {
    flex-basis: 100%;
  }
}

@media (prefers-reduced-motion: reduce) {
  .pw-tracking[data-state="running"][data-motion="on"] .pw-tracking-marker {
    transition: none;
  }

  .pw-tracking .pw-tracking-orbit,
  .pw-tracking[data-state="running"][data-motion="on"] .pw-tracking-orbit {
    animation: none;
    will-change: auto;
  }
}

/* Os elementos nativos com hidden continuam fora do layout, mesmo quando
   um seletor de componente ou de container declara display explicitamente. */
.pw-tracking [hidden],
.pw-tracking .pw-tracking-marker[hidden],
.pw-tracking .pw-tracking-step[hidden] {
  display: none;
}

/* Polls conservam o detalhe e o player enquanto só a fila e as medidas mudam. */
.pw-workspace.pw-workspace-solo { grid-template-columns: minmax(0, 1fr); }
.pw-workspace > .pw-queue[hidden] { display: none; }
.pw-detail-title-row > .pw-detail-progress { width: min(260px, 34%); flex: 0 0 auto; }
.pw-detail-title-row > .pw-detail-progress:empty { display: none; }
.pw-tracking .pw-tracking-waiting {
  display: block; position: relative; width: 38px; height: 38px; margin: 0 0 22px;
  border: 1px solid var(--pw-line); border-radius: 50%;
  animation: pw-tracking-orbit-turn 3s linear infinite; animation-play-state: paused;
}
.pw-tracking .pw-tracking-waiting > i {
  position: absolute; width: 7px; height: 7px; top: -4px; left: calc(50% - 3.5px);
  border-radius: 50%; background: var(--pw-red);
}
.pw-tracking[data-state="unknown"][data-motion="on"] .pw-tracking-waiting { animation-play-state: running; }
.pw-tracking .pw-tracking-waiting[hidden] { display: none; }
@media (prefers-reduced-motion: reduce) {
  .pw-tracking .pw-tracking-waiting { animation: none; }
}
@container pw-detail (max-width: 760px) {
  .pw-detail-title-row > .pw-detail-progress { width: 100%; }
}

/* Arquivos e publicação — acesso ao arquivo e texto para copiar.
   Esta extensão fica nas duas abas do workspace; o espelho do simulador e
   as demais entregas conservam suas regras. Vazios descrevem a ausência. */
.pw-delivery.pw-delivery-studio,
.pw-meta-panel.pw-meta-studio {
  min-width: 0;
  max-width: 100%;
  color: var(--pw-text, #f3f4f6);
  font-family: Geist, Arial, sans-serif;
  font-size: 14px;
  line-height: 1.6;
}

.pw-delivery.pw-delivery-studio *,
.pw-meta-panel.pw-meta-studio * {
  box-sizing: border-box;
}

.pw-delivery.pw-delivery-studio .pw-output-heading,
.pw-meta-panel.pw-meta-studio > .pw-panel-heading {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 16px 28px;
  min-width: 0;
  margin: 0 0 24px;
  padding: 0;
  border: 0;
}

.pw-delivery.pw-delivery-studio .pw-output-heading {
  display: block;
}

.pw-delivery.pw-delivery-studio .pw-output-heading h3,
.pw-meta-panel.pw-meta-studio > .pw-panel-heading h3 {
  margin: 0;
  color: var(--pw-text, #f3f4f6);
  font: 650 28px/1.2 Geist, Arial, sans-serif;
  letter-spacing: -.025em;
  overflow-wrap: anywhere;
}

.pw-delivery.pw-delivery-studio .pw-output-heading p,
.pw-meta-panel.pw-meta-studio > .pw-panel-heading p {
  max-width: 68ch;
  margin: 10px 0 0;
  color: var(--pw-muted, #9ca3b0);
  font-size: 14px;
  line-height: 1.65;
  overflow-wrap: anywhere;
}

.pw-delivery.pw-delivery-studio .pw-output-info {
  min-width: 0;
  max-width: 100%;
}

.pw-delivery.pw-delivery-studio .pw-output-file-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  min-width: 0;
  padding: 20px 0;
  border-top: 1px solid var(--pw-line, #292d37);
  border-bottom: 1px solid var(--pw-line, #292d37);
}

.pw-delivery.pw-delivery-studio .pw-output-name {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  flex: 1 1 260px;
  min-width: 0;
}

.pw-delivery.pw-delivery-studio .pw-output-name > svg {
  width: 24px;
  height: 24px;
  flex: 0 0 auto;
  margin-top: 2px;
  color: var(--pw-muted, #9ca3b0);
}

.pw-delivery.pw-delivery-studio .pw-output-name > div {
  min-width: 0;
}

.pw-delivery.pw-delivery-studio .pw-output-info {
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.pw-delivery.pw-delivery-studio .pw-output-name h4 {
  margin: 0;
  color: var(--pw-text, #f3f4f6);
  font: 600 18px/1.45 Geist, Arial, sans-serif;
  letter-spacing: -.015em;
  overflow-wrap: anywhere;
}

.pw-delivery.pw-delivery-studio .pw-output-name p {
  margin: 6px 0 0;
  color: var(--pw-muted, #9ca3b0);
  font-size: 14px;
  line-height: 1.6;
  overflow-wrap: anywhere;
}

.pw-delivery.pw-delivery-studio .pw-delivery-facts {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 24px;
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.pw-delivery.pw-delivery-studio .pw-delivery-facts:empty {
  display: none;
}

.pw-delivery.pw-delivery-studio .pw-delivery-facts > div {
  min-width: 0;
  margin: 0;
  padding: 0;
}

.pw-delivery.pw-delivery-studio .pw-delivery-facts > div + div {
  padding: 0;
  border: 0;
}

.pw-delivery.pw-delivery-studio .pw-delivery-facts dt {
  margin: 0 0 5px;
  color: var(--pw-muted, #9ca3b0);
  font-size: 13px;
  line-height: 1.5;
}

.pw-delivery.pw-delivery-studio .pw-delivery-facts dd {
  margin: 0;
  overflow: visible;
  color: var(--pw-text, #f3f4f6);
  font-size: 17px;
  font-weight: 600;
  line-height: 1.5;
  font-variant-numeric: tabular-nums;
  text-overflow: clip;
  white-space: normal;
  overflow-wrap: anywhere;
}

.pw-delivery.pw-delivery-studio .pw-output-access {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  min-width: 0;
  color: var(--pw-muted, #9ca3b0);
}

.pw-delivery.pw-delivery-studio .pw-output-access > svg {
  width: 20px;
  height: 20px;
  flex: 0 0 auto;
  margin-top: 2px;
}

.pw-delivery.pw-delivery-studio .pw-output-access[data-connected="true"] > svg {
  color: var(--pw-green, #54d69b);
}

.pw-delivery.pw-delivery-studio .pw-output-access[data-connected="false"] > svg {
  color: var(--pw-amber, #f2bb5e);
}

.pw-delivery.pw-delivery-studio .pw-output-access p {
  min-width: 0;
  margin: 0;
  color: var(--pw-muted, #9ca3b0);
  font-size: 13px;
  line-height: 1.6;
  overflow-wrap: anywhere;
}

.pw-delivery.pw-delivery-studio .pw-output-access strong {
  display: block;
  margin-bottom: 3px;
  color: #c5cbd4;
  font-size: 14px;
  font-weight: 550;
}

.pw-delivery.pw-delivery-studio .pw-output-access span {
  display: block;
}

.pw-delivery.pw-delivery-studio .pw-local-action-error {
  margin: 0;
  max-width: 68ch;
  color: var(--danger-text, #ff746a);
  font-size: 14px;
  line-height: 1.6;
  overflow-wrap: anywhere;
}

.pw-delivery.pw-delivery-studio .pw-delivery-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: 8px;
  min-width: 0;
}

.pw-delivery.pw-delivery-studio .pw-button,
.pw-meta-panel.pw-meta-studio .pw-button {
  min-height: 44px;
  max-width: 100%;
  padding: 10px 14px;
  border-radius: 6px;
  box-shadow: none;
  font-family: Geist, Arial, sans-serif;
  font-size: 14px;
  line-height: 1.4;
  text-align: center;
  white-space: normal;
  overflow-wrap: anywhere;
}

.pw-delivery.pw-delivery-studio .pw-button > svg,
.pw-meta-panel.pw-meta-studio .pw-button > svg {
  flex: 0 0 auto;
}

.pw-delivery.pw-delivery-studio .pw-button:focus-visible,
.pw-delivery.pw-delivery-studio summary:focus-visible,
.pw-meta-panel.pw-meta-studio .pw-button:focus-visible,
.pw-meta-panel.pw-meta-studio .pw-meta-campo:focus-visible {
  outline: 2px solid var(--pw-red, #ff4545);
  outline-offset: 3px;
}

.pw-delivery.pw-delivery-studio .pw-button:disabled,
.pw-meta-panel.pw-meta-studio .pw-button:disabled {
  opacity: .6;
  cursor: default;
}

.pw-delivery.pw-delivery-studio .pw-button[aria-busy="true"],
.pw-meta-panel.pw-meta-studio .pw-button[aria-busy="true"] {
  cursor: wait;
}

.pw-delivery.pw-delivery-studio .pw-button:active:not(:disabled),
.pw-meta-panel.pw-meta-studio .pw-button:active:not(:disabled) {
  border-color: var(--pw-red, #ff4545);
}

.pw-delivery.pw-delivery-studio .pw-published-path {
  display: block;
  min-width: 0;
  max-width: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  border-top: 1px solid var(--pw-line, #292d37);
  border-radius: 0;
  background: none;
}

.pw-delivery.pw-delivery-studio .pw-published-path > summary {
  position: relative;
  display: flex;
  align-items: center;
  min-height: 44px;
  padding: 12px 28px 12px 0;
  color: var(--pw-muted, #9ca3b0);
  font-size: 13px;
  font-weight: 500;
  line-height: 1.5;
  list-style: none;
  cursor: pointer;
  overflow-wrap: anywhere;
}

.pw-delivery.pw-delivery-studio .pw-published-path > summary::-webkit-details-marker {
  display: none;
}

.pw-delivery.pw-delivery-studio .pw-published-path > summary::marker {
  content: "";
}

.pw-delivery.pw-delivery-studio .pw-published-path > summary::after {
  position: absolute;
  top: calc(50% - 5px);
  right: 8px;
  width: 7px;
  height: 7px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  content: "";
  transform: rotate(45deg);
}

.pw-delivery.pw-delivery-studio .pw-published-path[open] > summary::after {
  top: calc(50% - 2px);
  transform: rotate(225deg);
}

.pw-delivery.pw-delivery-studio .pw-published-path code {
  display: block;
  min-width: 0;
  max-width: 100%;
  margin: 0 0 12px;
  padding: 12px;
  border: 0;
  border-radius: 4px;
  background: var(--pw-surface-quiet, #0e1015);
  color: #c5cbd4;
  font-family: var(--font-mono, "Geist Mono"), monospace;
  font-size: 12px;
  line-height: 1.65;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  user-select: text;
}

.pw-delivery.pw-delivery-studio .pw-published-path .pw-copy-path {
  width: auto;
  max-width: 100%;
  margin: 0;
}

.pw-delivery.pw-delivery-studio .pw-output-extras {
  min-width: 0;
  margin-top: 28px;
}

.pw-delivery.pw-delivery-studio .pw-output-extras .pw-delivery-file {
  min-height: 88px;
  margin: 0;
  padding: 18px 0;
  gap: 16px 24px;
}

.pw-delivery.pw-delivery-studio .pw-delivery-file-main {
  min-width: 0;
  flex: 1 1 auto;
}

.pw-delivery.pw-delivery-studio .pw-delivery-file-main > svg {
  flex: 0 0 auto;
  color: var(--pw-muted, #9ca3b0);
}

.pw-delivery.pw-delivery-studio .pw-delivery-file strong {
  overflow: visible;
  color: var(--pw-text, #f3f4f6);
  font-size: 15px;
  line-height: 1.5;
  text-overflow: clip;
  white-space: normal;
  overflow-wrap: anywhere;
}

.pw-delivery.pw-delivery-studio .pw-delivery-file span {
  color: var(--pw-muted, #9ca3b0);
  font-size: 13px;
  line-height: 1.6;
  overflow-wrap: anywhere;
}

.pw-delivery.pw-delivery-studio .pw-file-erro,
.pw-meta-panel.pw-meta-studio .pw-meta-erro {
  padding: 14px 16px;
  font-size: 14px;
  line-height: 1.6;
  overflow-wrap: anywhere;
}

/* A descrição ocupa a coluna de leitura; tags e capítulos ficam ao lado. */
.pw-meta-panel.pw-meta-studio {
  display: block;
}

.pw-meta-panel.pw-meta-studio > .pw-panel-heading > div {
  min-width: 0;
}

.pw-meta-panel.pw-meta-studio > .pw-panel-heading > div:first-child {
  flex: 1 1 260px;
}

.pw-meta-panel.pw-meta-studio > .pw-panel-heading .pw-meta-billing {
  display: block;
  max-width: 34ch;
  margin: 8px 0 0;
  color: var(--pw-muted, #9ca3b0);
  font-size: 12px;
  line-height: 1.6;
  overflow-wrap: anywhere;
}

.pw-meta-panel.pw-meta-studio .pw-meta-saida:not(:empty) {
  margin-bottom: 20px;
}

.pw-meta-panel.pw-meta-studio .pw-meta-grid {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
  align-items: start;
  gap: 28px;
  min-width: 0;
  margin-top: 24px;
}

.pw-meta-panel.pw-meta-studio .pw-meta-bloco,
.pw-meta-panel.pw-meta-studio .pw-meta-sidebar {
  min-width: 0;
  max-width: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
}

.pw-meta-panel.pw-meta-studio .pw-meta-sidebar {
  padding-left: 24px;
  border-left: 1px solid var(--pw-line, #292d37);
}

.pw-meta-panel.pw-meta-studio .pw-meta-bloco > header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px 12px;
  min-height: 44px;
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.pw-meta-panel.pw-meta-studio .pw-meta-bloco h3 {
  min-width: 0;
  margin: 0;
  color: var(--pw-text, #f3f4f6);
  font: 600 17px/1.45 Geist, Arial, sans-serif;
  letter-spacing: -.015em;
  overflow-wrap: anywhere;
}

.pw-meta-panel.pw-meta-studio .pw-meta-bloco > .dica,
.pw-meta-panel.pw-meta-studio .pw-meta-dica {
  max-width: 68ch;
  margin: 6px 0 0;
  color: var(--pw-muted, #9ca3b0);
  font-size: 13px;
  line-height: 1.6;
  overflow-wrap: anywhere;
}

.pw-meta-panel.pw-meta-studio .pw-meta-copiar {
  flex: 0 0 auto;
  min-width: 96px;
}

.pw-meta-panel.pw-meta-studio .pw-meta-campo {
  display: block;
  width: 100%;
  min-width: 0;
  min-height: 320px;
  max-width: 100%;
  margin: 16px 0 0;
  padding: 18px;
  border: 1px solid var(--pw-line, #292d37);
  border-radius: 6px;
  background: var(--pw-surface-quiet, #0e1015);
  color: #d9dde4;
  caret-color: var(--pw-red, #ff4545);
  font: 400 14px/1.75 Geist, Arial, sans-serif;
  resize: vertical;
  scrollbar-color: #505864 var(--pw-surface-quiet, #0e1015);
}

.pw-meta-panel.pw-meta-studio .pw-meta-campo[readonly] {
  opacity: 1;
  cursor: text;
}

.pw-meta-panel.pw-meta-studio .pw-meta-campo::selection,
.pw-delivery.pw-delivery-studio .pw-published-path code::selection {
  background: #842424;
  color: #fff;
}

.pw-meta-panel.pw-meta-studio .pw-meta-blank {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 12px;
  min-width: 0;
  min-height: 280px;
  margin: 16px 0 0;
  padding: 28px;
  border: 1px solid var(--pw-line, #292d37);
  border-radius: 6px;
  background: var(--pw-surface-quiet, #0e1015);
}

.pw-meta-panel.pw-meta-studio .pw-meta-blank > svg {
  display: block;
  width: 32px;
  height: 32px;
  flex: 0 0 auto;
  margin-bottom: 4px;
  color: var(--pw-muted, #9ca3b0);
  stroke-width: 1.5;
}

.pw-meta-panel.pw-meta-studio .pw-meta-blank h4 {
  margin: 0;
  color: var(--pw-text, #f3f4f6);
  font: 600 17px/1.45 Geist, Arial, sans-serif;
  letter-spacing: -.015em;
}

.pw-meta-panel.pw-meta-studio .pw-meta-blank p {
  max-width: 52ch;
  margin: 0;
  color: var(--pw-muted, #9ca3b0);
  font-size: 14px;
  line-height: 1.65;
  overflow-wrap: anywhere;
}

.pw-meta-panel.pw-meta-studio .pw-tag-list {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 8px;
  min-width: 0;
  margin: 16px 0 0;
  padding: 0;
  list-style: none;
}

.pw-meta-panel.pw-meta-studio .pw-tag-list > li {
  min-width: 0;
  max-width: 100%;
  margin: 0;
  padding: 6px 9px;
  border: 1px solid var(--pw-line, #292d37);
  border-radius: 4px;
  background: var(--pw-surface-raised, #171920);
  color: #c5cbd4;
  font-size: 13px;
  line-height: 1.5;
  overflow-wrap: anywhere;
}

.pw-meta-panel.pw-meta-studio .pw-meta-empty-copy {
  max-width: 52ch;
  margin: 18px 0 0;
  color: var(--pw-muted, #9ca3b0);
  font-size: 14px;
  line-height: 1.65;
  overflow-wrap: anywhere;
}

.pw-meta-panel.pw-meta-studio .pw-meta-chapters {
  min-width: 0;
  margin-top: 24px;
  padding-top: 20px;
  border-top: 1px solid var(--pw-line, #292d37);
}

.pw-meta-panel.pw-meta-studio .pw-meta-chapters h4 {
  margin: 0;
  color: #c5cbd4;
  font: 550 15px/1.5 Geist, Arial, sans-serif;
  letter-spacing: 0;
}

.pw-meta-panel.pw-meta-studio .pw-meta-chapters p {
  max-width: 52ch;
  margin: 6px 0 0;
  color: var(--pw-muted, #9ca3b0);
  font-size: 13px;
  line-height: 1.65;
  overflow-wrap: anywhere;
}

@media (hover: hover) {
  .pw-delivery.pw-delivery-studio .pw-published-path > summary:hover {
    color: var(--pw-text, #f3f4f6);
  }
}

@container pw-detail (max-width: 760px) {
  .pw-meta-panel.pw-meta-studio .pw-meta-grid {
    grid-template-columns: minmax(0, 1fr);
    gap: 24px;
  }

  .pw-delivery.pw-delivery-studio .pw-output-info {
    gap: 16px;
  }

  .pw-meta-panel.pw-meta-studio .pw-meta-sidebar {
    padding-top: 24px;
    padding-left: 0;
    border-top: 1px solid var(--pw-line, #292d37);
    border-left: 0;
  }

  .pw-meta-panel.pw-meta-studio .pw-meta-blank {
    min-height: 240px;
  }

  .pw-delivery.pw-delivery-studio .pw-output-extras .pw-delivery-file {
    align-items: flex-start;
    flex-direction: column;
  }
}

@container pw-detail (max-width: 620px) {
  .pw-delivery.pw-delivery-studio .pw-output-heading h3,
  .pw-meta-panel.pw-meta-studio > .pw-panel-heading h3 {
    font-size: 26px;
  }

  .pw-delivery.pw-delivery-studio .pw-delivery-actions {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    width: 100%;
  }

  .pw-delivery.pw-delivery-studio .pw-delivery-actions .pw-button {
    width: 100%;
  }

  .pw-meta-panel.pw-meta-studio > .pw-panel-heading {
    flex-direction: column;
    align-items: stretch;
    gap: 20px;
  }

  .pw-meta-panel.pw-meta-studio > .pw-panel-heading > div:first-child {
    flex-basis: auto;
  }

  .pw-meta-panel.pw-meta-studio > .pw-panel-heading .pw-meta-billing {
    max-width: 52ch;
  }

  .pw-meta-panel.pw-meta-studio .pw-meta-campo {
    min-height: 280px;
    padding: 16px;
  }

  .pw-meta-panel.pw-meta-studio .pw-meta-blank {
    min-height: 220px;
    padding: 22px;
  }
}

.pw-delivery.pw-delivery-studio [hidden],
.pw-meta-panel.pw-meta-studio [hidden] {
  display: none;
}
