primocode 9.8.0-beta.2 → 9.8.0-beta.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/README.md +33 -6
  2. package/app/ansi.js +55 -0
  3. package/app/app.css +482 -281
  4. package/app/app.js +888 -315
  5. package/app/index.html +176 -101
  6. package/app/primo-marca.js +58 -1
  7. package/bin/primocode.js +697 -118
  8. package/comandos/explicar.md +14 -0
  9. package/comandos/publicar.md +10 -0
  10. package/comandos/revisar.md +13 -0
  11. package/lib/act.js +130 -26
  12. package/lib/api.js +8 -1
  13. package/lib/app.js +317 -74
  14. package/lib/browser.js +79 -3
  15. package/lib/catalogo.js +11 -3
  16. package/lib/checkpoint-git.js +218 -0
  17. package/lib/checkpoint.js +249 -0
  18. package/lib/claude-engine.js +25 -3
  19. package/lib/comandos-extra.js +481 -0
  20. package/lib/comandos.js +104 -0
  21. package/lib/config.js +21 -4
  22. package/lib/estudio/acervo-site.js +157 -0
  23. package/lib/estudio/assets.js +77 -3
  24. package/lib/estudio/cinema.js +277 -0
  25. package/lib/estudio/composicao.js +470 -0
  26. package/lib/estudio/edicao.js +450 -0
  27. package/lib/estudio/impacto.js +263 -0
  28. package/lib/estudio/index.js +674 -5
  29. package/lib/estudio/plano.js +5 -2
  30. package/lib/estudio/remotion.js +228 -23
  31. package/lib/estudio/slides.js +34 -30
  32. package/lib/fala.js +95 -1
  33. package/lib/local/cerebro.json +361 -180
  34. package/lib/local/entrada.js +18 -8
  35. package/lib/local/motor-cli.js +1 -1
  36. package/lib/mencoes.js +98 -0
  37. package/lib/offline.js +168 -0
  38. package/lib/painel.js +291 -0
  39. package/lib/perigo.js +256 -0
  40. package/lib/pre-leitura.js +118 -0
  41. package/lib/repeticao.js +4 -2
  42. package/lib/skills.js +6 -1
  43. package/lib/tempos.js +62 -0
  44. package/lib/ui.js +171 -17
  45. package/package.json +3 -2
  46. package/skills/apresentacao-pptx/SKILL.md +52 -0
  47. package/skills/cartaz-de-arte/LICENSE.txt +202 -0
  48. package/skills/cartaz-de-arte/SKILL.md +47 -0
  49. package/skills/criar-skill/LICENSE.txt +202 -0
  50. package/skills/criar-skill/SKILL.md +49 -0
  51. package/skills/depurar-de-verdade/LICENSE.txt +21 -0
  52. package/skills/depurar-de-verdade/SKILL.md +14 -5
  53. package/skills/design-de-verdade/LICENSE.txt +177 -0
  54. package/skills/design-de-verdade/SKILL.md +42 -0
  55. package/skills/documento-word/SKILL.md +57 -0
  56. package/skills/interface-revisada/SKILL.md +47 -0
  57. package/skills/me-ensina/LICENSE.txt +21 -0
  58. package/skills/me-ensina/SKILL.md +27 -0
  59. package/skills/me-entrevista/LICENSE.txt +21 -0
  60. package/skills/me-entrevista/SKILL.md +27 -0
  61. package/skills/motion-de-primeira/SKILL.md +1 -1
  62. package/skills/pdf-bonito/SKILL.md +48 -0
  63. package/skills/planilha-excel/SKILL.md +47 -0
  64. package/skills/react-sem-dor/SKILL.md +48 -0
  65. package/skills/revisao-antes-de-entregar/LICENSE.txt +21 -0
  66. package/skills/revisao-antes-de-entregar/SKILL.md +6 -1
  67. package/skills/site-com-motion/SKILL.md +39 -0
  68. package/skills/temas-prontos/LICENSE.txt +202 -0
  69. package/skills/temas-prontos/SKILL.md +50 -0
  70. package/skills/testar-o-site/LICENSE.txt +202 -0
  71. package/skills/testar-o-site/SKILL.md +46 -0
  72. package/skills/video-no-remotion/SKILL.md +48 -0
  73. package/studio/narrar.py +111 -10
package/app/app.css CHANGED
@@ -1,299 +1,500 @@
1
1
  /* A janela do PrimoCode.
2
2
  *
3
- * "Um aplicativo desktop bem bonito com as cores do PrimoCode, com aquele
4
- * azul. Bem estilo Codex. Um chat estilo terminal para quem não quer o
5
- * terminal."
3
+ * O desenho segue o de um app de mesa de agente, cinza e calmo: fundo
4
+ * neutro, barra lateral um degrau mais clara, compositor mais clara ainda, e
5
+ * cor só onde ela quer dizer alguma coisa — o laranja do "Acesso completo"
6
+ * (o agente não pergunta nada, nem antes do que não tem volta), o ciano da
7
+ * marca no botão de enviar quando há o que enviar, verde e vermelho só nos
8
+ * números de linha de uma edição.
6
9
  *
7
- * As cores não foram escolhidas aqui: são as mesmas de lib/ui.js, que já vêm
8
- * do design system do produto. cyan-400 é o azul do PrimoCode; slate é a
9
- * neutra; amber avisa e rose reprova. Repetir o terminal na tela não é falta
10
- * de imaginação — é o que faz as duas telas serem o MESMO produto.
10
+ * Tema escuro primeiro, porque é o da janela. O claro redefine SÓ os tokens:
11
+ * nenhum componente tem cor própria fora do :root, então trocar o tema troca
12
+ * a tela inteira, não metade dela.
11
13
  */
12
14
 
13
15
  :root {
14
- --azul: #22d3ee; /* cyan-400 — a marca */
15
- --azul-fundo: #0891b2; /* cyan-600 — a mesma cor recuando */
16
- --texto: #e2e8f0; /* slate-200 */
17
- --fraco: #94a3b8; /* slate-400 */
18
- --apagado: #64748b; /* slate-500 */
19
- --alerta: #fbbf24; /* amber-400 */
20
- --falha: #fb7185; /* rose-400 */
21
-
22
- --fundo: #0a0f16;
23
- --painel: #0f1620;
24
- --borda: #1e293b;
25
- --borda-viva: #24384f;
26
-
27
- --mono: ui-monospace, "SF Mono", "JetBrains Mono", "Cascadia Mono", Menlo,
28
- Consolas, "Liberation Mono", monospace;
29
- --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, system-ui, sans-serif;
30
-
31
- /* A barra lateral e o diálogo de configurações. Nomes novos, mesma
32
- família de cores — nada aqui inventa cor: tudo sai das de cima. */
33
- --barra: #0b1119;
34
- --alto: #16202c;
35
- --largura-lado: 262px;
36
- }
37
-
38
- /* Tema claro. Só os TOKENS mudam; nenhuma regra abaixo sabe que ele existe,
39
- e é isso que faz o tema inteiro caber em vinte linhas. */
40
- html[data-tema="claro"] {
41
- --azul: #0e7490;
42
- --azul-fundo: #0891b2;
43
- --texto: #0f1922;
44
- --fraco: #46596b;
45
- --apagado: #7b8fa1;
46
- --fundo: #f4f7f9;
47
- --painel: #ffffff;
48
- --borda: #d5e0e7;
49
- --borda-viva: #b7c8d3;
50
- --barra: #eef3f6;
51
- --alto: #e3ebf0;
52
- }
53
- /* A cor de acento escolhida nas configurações. */
54
- html[data-cor="verde"] { --azul:#34d399; --azul-fundo:#10b981; }
55
- html[data-cor="roxo"] { --azul:#a78bfa; --azul-fundo:#8b5cf6; }
56
- html[data-cor="ambar"] { --azul:#fbbf24; --azul-fundo:#d97706; }
57
- html[data-cor="rosa"] { --azul:#fb7185; --azul-fundo:#e11d48; }
58
-
59
- * { box-sizing: border-box; }
16
+ color-scheme: dark;
17
+ --fundo: #181818;
18
+ --lado: #262626;
19
+ --compositor: #2f2f2f;
20
+ --barra-projeto: #202020;
21
+ --elevado: #2a2a2a;
22
+ --menu: #2b2b2b;
23
+ --borda: rgba(255, 255, 255, 0.07);
24
+ --borda-forte: rgba(255, 255, 255, 0.12);
25
+ --hover: rgba(255, 255, 255, 0.055);
26
+ --ativo: rgba(255, 255, 255, 0.085);
27
+ --texto: #ececec;
28
+ --texto-2: #cfcfcf;
29
+ --fraco: #8d8d8d;
30
+ --mais-fraco: #6a6a6a;
31
+ --balao: #2c2c2c;
32
+ --codigo: #111111;
33
+ --marca: #22d3ee;
34
+ --marca-texto: #06232a;
35
+ --enviar-off: #34425a;
36
+ --enviar-off-texto: #8391a8;
37
+ --laranja: #f08b4f;
38
+ --mais-linha: #5fcf8a;
39
+ --menos-linha: #f07a7a;
40
+ --aviso: #f0b64f;
41
+ --avatar: #3a6bd6;
42
+ --sombra: 0 12px 32px rgba(0, 0, 0, 0.45), 0 0 0 1px rgba(255, 255, 255, 0.06);
43
+ --fonte: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", system-ui, Roboto, "Helvetica Neue", Arial, sans-serif;
44
+ --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
45
+ --largura-lado: 272px;
46
+ --largura-conversa: 736px;
47
+ --largura-painel: 44%;
48
+ }
60
49
 
61
- /* `display:flex` e `display:grid` nas regras abaixo ganham do `[hidden]` do
62
- navegador, que é só `display:none` sem peso nenhum. O resultado era o botão
63
- de parar e o "trabalhando" aparecendo com o agente parado — a janela dizia
64
- que estava fazendo alguma coisa o tempo todo. */
65
- [hidden] { display: none !important; }
50
+ :root[data-tema="claro"] {
51
+ color-scheme: light;
52
+ --fundo: #ffffff;
53
+ --lado: #f4f4f3;
54
+ --compositor: #ffffff;
55
+ --barra-projeto: #f4f4f3;
56
+ --elevado: #f7f7f6;
57
+ --menu: #ffffff;
58
+ --borda: rgba(0, 0, 0, 0.08);
59
+ --borda-forte: rgba(0, 0, 0, 0.14);
60
+ --hover: rgba(0, 0, 0, 0.045);
61
+ --ativo: rgba(0, 0, 0, 0.07);
62
+ --texto: #1d1d1d;
63
+ --texto-2: #3a3a3a;
64
+ --fraco: #6f6f6f;
65
+ --mais-fraco: #9a9a9a;
66
+ --balao: #f1f1f0;
67
+ --codigo: #f6f6f5;
68
+ --marca: #0e7490;
69
+ --marca-texto: #ffffff;
70
+ --enviar-off: #d9dde6;
71
+ --enviar-off-texto: #8a93a4;
72
+ --laranja: #c75a17;
73
+ --mais-linha: #1a7f45;
74
+ --menos-linha: #c23a3a;
75
+ --aviso: #9a6200;
76
+ --sombra: 0 12px 32px rgba(0, 0, 0, 0.12), 0 0 0 1px rgba(0, 0, 0, 0.08);
77
+ }
66
78
 
67
- html, body {
68
- height: 100%;
79
+ * { box-sizing: border-box; }
80
+ html, body { height: 100%; }
81
+ body {
69
82
  margin: 0;
70
83
  background: var(--fundo);
71
84
  color: var(--texto);
72
- font-family: var(--sans);
73
- font-size: 14px;
85
+ font: 14px/1.45 var(--fonte);
86
+ -webkit-font-smoothing: antialiased;
74
87
  overflow: hidden;
75
88
  }
89
+ [hidden] { display: none !important; }
90
+ button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
91
+ button:focus-visible, textarea:focus-visible, input:focus-visible, [tabindex]:focus-visible {
92
+ outline: 2px solid var(--marca);
93
+ outline-offset: 1px;
94
+ }
95
+ .ic {
96
+ width: 18px; height: 18px; flex: none;
97
+ fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round;
98
+ }
99
+ .ic-p { width: 14px; height: 14px; }
100
+ .espaco { flex: 1; }
101
+ .fraco { color: var(--fraco); }
102
+
103
+ .icone-btn {
104
+ display: inline-grid; place-items: center;
105
+ width: 28px; height: 28px; border-radius: 7px;
106
+ color: var(--fraco);
107
+ }
108
+ .icone-btn:hover { background: var(--hover); color: var(--texto); }
109
+ .icone-btn[aria-pressed="true"] { color: var(--marca); }
110
+ .icone-btn.grande .ic { width: 20px; height: 20px; }
111
+
112
+ /* ── o esqueleto ───────────────────────────────────────────────────────── */
113
+
114
+ .app { display: flex; height: 100%; }
76
115
 
77
- body {
78
- /* O brilho azul atrás de tudo. Um só, bem aberto e bem fraco: dá
79
- profundidade sem virar papel de parede. */
80
- background-image:
81
- radial-gradient(120% 80% at 50% -20%, rgba(34, 211, 238, .08), transparent 62%);
82
- }
83
-
84
- /* ── a mesma planta da página /code do Conecta ──────────────────────────
85
- Barra lateral fixa à esquerda, conversa ocupando o resto. As duas telas
86
- são o mesmo produto e têm de ser reconhecíveis uma na outra no primeiro
87
- olhar — quem sai do terminal para a janela ou do celular para a janela
88
- não pode ter de reaprender onde ficam as coisas. */
89
- .tela { display: flex; height: 100%; }
90
116
  .lado {
91
- width: var(--largura-lado); flex: 0 0 var(--largura-lado);
92
- background: var(--barra); border-right: 1px solid var(--borda);
93
- display: flex; flex-direction: column; min-height: 0;
94
- -webkit-app-region: drag;
95
- }
96
- .lado button, .lado .chip { -webkit-app-region: no-drag; }
97
- .lado-topo { padding: 14px 12px 10px; display: flex; flex-direction: column; gap: 12px; }
98
- .marca-linha { display: flex; align-items: center; gap: 9px; padding: 0 4px; }
99
- .marca-linha .nome { font-weight: 620; letter-spacing: -.01em; }
100
- .marca-linha .versao { margin-left: auto; font-family: var(--mono); font-size: 11px; color: var(--apagado); }
101
-
102
- .novo {
103
- display: flex; align-items: center; gap: 9px; width: 100%;
104
- padding: 9px 12px; border-radius: 9px; cursor: pointer;
105
- background: var(--alto); border: 1px solid var(--borda-viva);
106
- color: inherit; font: inherit; font-size: 13.5px; font-weight: 500;
107
- transition: border-color .15s;
108
- }
109
- .novo:hover { border-color: var(--azul); }
110
-
111
- .rotulo { padding: 14px 16px 6px; font-size: 11px; letter-spacing: .08em;
112
- text-transform: uppercase; color: var(--apagado); }
113
- .recentes { flex: 1 1 0; min-height: 0; overflow-y: auto; padding: 0 8px 8px; }
117
+ width: var(--largura-lado); flex: none;
118
+ display: flex; flex-direction: column;
119
+ background: var(--lado);
120
+ border-right: 1px solid var(--borda);
121
+ min-height: 0;
122
+ }
123
+ .app.sem-lado .lado { display: none; }
124
+ #btnLadoAbrir { display: none; }
125
+ .app.sem-lado #btnLadoAbrir { display: inline-grid; }
126
+
127
+ .lado-barra { height: 42px; display: flex; align-items: center; padding: 0 12px; }
128
+
129
+ .lado-marca {
130
+ display: flex; align-items: center; justify-content: space-between;
131
+ padding: 0 10px 0 12px; height: 40px;
132
+ }
133
+ .marca-btn {
134
+ display: inline-flex; align-items: center; gap: 6px;
135
+ font-size: 17px; font-weight: 600; letter-spacing: -0.01em;
136
+ padding: 3px 6px; margin-left: -6px; border-radius: 7px;
137
+ }
138
+ .marca-btn .ic { color: var(--fraco); }
139
+ .marca-btn:hover { background: var(--hover); }
140
+ .lado-acoes { display: flex; gap: 4px; }
141
+
142
+ .busca { padding: 4px 10px 6px; }
143
+ .busca input {
144
+ width: 100%; height: 30px; padding: 0 10px;
145
+ background: var(--fundo); color: var(--texto);
146
+ border: 1px solid var(--borda-forte); border-radius: 8px; font: inherit;
147
+ }
148
+
149
+ .nav { display: flex; flex-direction: column; gap: 1px; padding: 8px 6px 0; }
150
+ .nav-linha { display: flex; align-items: center; gap: 4px; }
151
+ .nav-linha .nav-item { flex: 1; }
152
+ .nav-linha .icone-btn { margin-right: 6px; }
153
+ .nav-item {
154
+ display: flex; align-items: center; gap: 11px;
155
+ height: 31px; padding: 0 9px; border-radius: 8px;
156
+ color: var(--texto); text-align: left; white-space: nowrap;
157
+ }
158
+ .nav-item .ic { color: var(--texto-2); }
159
+ .nav-item:hover { background: var(--hover); }
160
+ .nav-item.ativo { background: var(--ativo); }
161
+ .nav-item[aria-pressed="true"] { background: var(--ativo); }
162
+
163
+ .rolagem-lado { flex: 1; min-height: 0; overflow-y: auto; padding: 22px 6px 12px; }
164
+ .secao { color: var(--fraco); padding: 0 9px; height: 30px; display: flex; align-items: center; }
165
+ .lista { display: flex; flex-direction: column; gap: 1px; margin-bottom: 18px; }
166
+ .vazio-lista { color: var(--mais-fraco); padding: 0 9px; height: 34px; display: flex; align-items: center; }
114
167
  .item {
115
- display: block; width: 100%; text-align: left; padding: 8px 10px; cursor: pointer;
116
- border: 0; background: none; color: var(--fraco); font: inherit; font-size: 13px;
117
- border-radius: 8px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
118
- }
119
- .item:hover { background: var(--alto); color: var(--texto); }
120
- .item[aria-current="true"] { background: var(--alto); color: var(--texto); font-weight: 500; }
121
- .item .quando { display: block; font-size: 11px; color: var(--apagado); font-family: var(--mono); }
122
- .vazio-lista { padding: 6px 12px; font-size: 12.5px; color: var(--apagado); line-height: 1.5; }
123
- .vazio-lista code { font-family: var(--mono); color: var(--azul); }
124
-
125
- .lado-pe { border-top: 1px solid var(--borda); padding: 8px; display: flex; flex-direction: column; gap: 6px; }
126
- .pe-btn {
127
- display: flex; align-items: center; gap: 9px; padding: 8px 10px; cursor: pointer;
128
- border: 0; background: none; color: var(--fraco); font: inherit; font-size: 13.5px;
129
- border-radius: 8px; width: 100%; text-align: left;
130
- }
131
- .pe-btn:hover { background: var(--alto); color: var(--texto); }
132
- .chips { display: flex; flex-wrap: wrap; gap: 5px; padding: 0 4px 2px; }
133
- .chip {
134
- font-family: var(--mono); font-size: 11px; color: var(--fraco);
135
- background: var(--alto); border: 1px solid var(--borda);
136
- border-radius: 6px; padding: 2px 7px;
137
- max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
138
- }
139
- .chip:empty { display: none; }
140
-
141
- .conversa { flex: 1 1 auto; display: flex; flex-direction: column; min-width: 0; min-height: 0; }
142
- .rolo { flex: 1 1 0; overflow-y: auto; scroll-behavior: smooth; }
143
- .rolo::-webkit-scrollbar { width: 10px; }
144
- .rolo::-webkit-scrollbar-thumb { background: #1c2836; border-radius: 8px; border: 3px solid var(--fundo); }
145
- .tira { max-width: 860px; margin: 0 auto; padding: 26px 22px 40px; }
146
-
147
- .vazio { display: flex; flex-direction: column; align-items: center; gap: 14px;
148
- padding: 9vh 22px 0; text-align: center; }
149
- .vazio h1 { font-size: 26px; font-weight: 620; letter-spacing: -.025em; margin: 4px 0 0; }
150
- .vazio p { color: var(--fraco); max-width: 460px; margin: 0; line-height: 1.6; }
151
- .sugestoes { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; margin-top: 6px; }
152
- .sugestao {
153
- font: inherit; font-size: 13px; color: var(--fraco); cursor: pointer;
154
- background: var(--painel); border: 1px solid var(--borda);
155
- border-radius: 999px; padding: 7px 15px;
156
- transition: border-color .16s, color .16s, transform .16s;
157
- }
158
- .sugestao:hover { color: var(--texto); border-color: var(--azul); transform: translateY(-1px); }
159
-
160
- /* "trabalhando", com o ponto que pulsa. Fica ACIMA do campo, para não
161
- empurrar o texto que a pessoa está digitando. */
162
- #pensando {
163
- max-width: 860px; margin: 0 auto 9px; display: flex; align-items: center; gap: 8px;
164
- font-family: var(--mono); font-size: 12px; color: var(--apagado);
165
- }
166
- .pulso {
167
- width: 8px; height: 8px; border-radius: 50%; background: var(--azul);
168
- box-shadow: 0 0 0 0 rgba(34, 211, 238, .55);
169
- }
170
- @media (prefers-reduced-motion: no-preference) {
171
- .pulso { animation: bater 1.4s ease-out infinite; }
172
- @keyframes bater {
173
- to { box-shadow: 0 0 0 9px rgba(34, 211, 238, 0); }
174
- }
175
- }
176
- .dica {
177
- max-width: 860px; margin: 8px auto 0;
178
- color: var(--apagado); font-size: 11.5px; text-align: center;
179
- }
180
-
181
- .rodape { border-top: 1px solid var(--borda); background: rgba(10, 15, 22, .82);
182
- backdrop-filter: blur(14px); padding: 12px 22px 14px; }
183
- html[data-tema="claro"] .rodape { background: rgba(255, 255, 255, .85); }
184
- .caixa { max-width: 860px; margin: 0 auto; display: flex; align-items: flex-end; gap: 10px; }
185
- .campo-volta {
186
- flex: 1 1 auto; display: flex; align-items: flex-end; gap: 8px;
187
- background: var(--painel); border: 1px solid var(--borda-viva); border-radius: 12px;
188
- padding: 9px 12px; transition: border-color .15s;
189
- }
190
- .campo-volta:focus-within { border-color: var(--azul); }
191
- .chevron { font-family: var(--mono); color: var(--azul); font-weight: 600; padding-bottom: 1px; }
192
- /* O textarea entrega a moldura para a `.campo-volta`. Sem isto ele desenha a
193
- caixa DELE dentro da caixa de fora — duas bordas, uma dentro da outra. */
194
- #campo {
195
- flex: 1 1 auto; background: none; border: 0; outline: none; color: inherit;
196
- resize: none; font-family: var(--mono); font-size: 13.5px; line-height: 1.6;
197
- max-height: 190px; padding: 0;
198
- }
199
- #campo::placeholder { color: var(--apagado); }
168
+ display: flex; align-items: center; gap: 8px;
169
+ height: 31px; padding: 0 9px; border-radius: 8px;
170
+ color: var(--texto); text-align: left; width: 100%;
171
+ }
172
+ .item:hover { background: var(--hover); color: var(--texto); }
173
+ .item[aria-current="true"] { background: var(--ativo); color: var(--texto); }
174
+ .item .titulo { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
175
+ .item .quando { color: var(--mais-fraco); font-size: 12px; flex: none; font-variant-numeric: tabular-nums; }
176
+ .item .ic { width: 16px; height: 16px; color: var(--fraco); }
177
+ .dia { color: var(--mais-fraco); font-size: 12px; padding: 8px 9px 2px; }
178
+
179
+ .lado-pe {
180
+ display: flex; align-items: center; justify-content: space-between;
181
+ height: 54px; padding: 0 12px 0 14px; border-top: 1px solid var(--borda);
182
+ }
183
+ .usuario { display: flex; align-items: center; gap: 10px; min-width: 0; color: var(--texto-2); font-size: 14.5px; }
184
+ .nome-usuario { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
185
+ .avatar {
186
+ width: 20px; height: 20px; border-radius: 50%; flex: none;
187
+ display: grid; place-items: center;
188
+ background: var(--avatar); color: #fff; font-size: 8px; font-weight: 600; letter-spacing: 0.02em;
189
+ }
190
+
191
+ /* ── o centro ──────────────────────────────────────────────────────────── */
192
+
193
+ .centro { flex: 1; min-width: 0; display: flex; flex-direction: column; position: relative; }
194
+ .topo {
195
+ position: absolute; top: 0; left: 0; right: 0; z-index: 2;
196
+ height: 42px; display: flex; align-items: center; gap: 8px; padding: 0 12px;
197
+ pointer-events: none;
198
+ }
199
+ .topo > * { pointer-events: auto; }
200
+ .topo-titulo {
201
+ flex: 1; min-width: 0; text-align: center; color: var(--fraco); font-size: 13px;
202
+ overflow: hidden; text-overflow: ellipsis; white-space: nowrap; pointer-events: none;
203
+ }
204
+
205
+ .rolo { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; }
206
+ .vazio {
207
+ flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
208
+ gap: 22px; padding: 60px 24px 20px;
209
+ }
210
+ .vazio h1 { margin: 0; font-size: 26px; font-weight: 400; letter-spacing: -0.01em; text-wrap: balance; text-align: center; }
211
+ .mascote { color: var(--fraco); display: grid; place-items: center; }
212
+ .mascote.pequeno { color: var(--mais-fraco); }
213
+
214
+ .chat {
215
+ width: 100%; max-width: calc(var(--largura-conversa) + 48px); margin: 0 auto;
216
+ padding: 58px 24px 28px; display: flex; flex-direction: column; gap: 14px;
217
+ }
218
+
219
+ .msg-voce { display: flex; justify-content: flex-end; }
220
+ .msg-voce .balao {
221
+ max-width: 76%; background: var(--balao); padding: 9px 15px; border-radius: 18px;
222
+ white-space: pre-wrap; overflow-wrap: anywhere; font-size: 15px; line-height: 1.5;
223
+ }
224
+
225
+ .msg-primo { font-size: 15px; line-height: 1.62; overflow-wrap: anywhere; color: var(--texto); }
226
+ .msg-primo > :first-child { margin-top: 0; }
227
+ .msg-primo > :last-child { margin-bottom: 0; }
228
+ .msg-primo p { margin: 0 0 10px; }
229
+ .msg-primo h3, .msg-primo h4 { margin: 16px 0 6px; font-size: 15px; font-weight: 600; }
230
+ .msg-primo ul, .msg-primo ol { margin: 0 0 10px; padding-left: 22px; }
231
+ .msg-primo li { margin: 2px 0; }
232
+ .msg-primo code { font-family: var(--mono); font-size: 13px; background: var(--hover); padding: 1px 5px; border-radius: 5px; }
233
+ .msg-primo pre {
234
+ margin: 0 0 10px; padding: 12px 14px; background: var(--codigo); border: 1px solid var(--borda);
235
+ border-radius: 10px; overflow-x: auto; font: 12.5px/1.55 var(--mono);
236
+ }
237
+ .msg-primo pre code { background: none; padding: 0; font-size: inherit; }
238
+
239
+ .pensamento { color: var(--fraco); font-size: 14px; white-space: pre-wrap; }
240
+ .aviso-msg { color: var(--aviso); font-size: 14px; white-space: pre-wrap; }
241
+ .aviso-msg.erro { color: var(--menos-linha); }
242
+
243
+ /* A linha de ação: pequena, cinza, e só abre quando a pessoa quer. O agente
244
+ faz dez coisas por pedido; se cada uma ocupasse um bloco, a resposta —
245
+ que é o que importa — ficaria lá embaixo. */
246
+ .acoes { display: flex; flex-direction: column; gap: 0; }
247
+ .acao { color: var(--fraco); font-size: 13.5px; }
248
+ .acao-linha {
249
+ display: flex; align-items: center; gap: 8px; width: 100%;
250
+ min-height: 28px; padding: 3px 8px; margin-left: -8px; border-radius: 7px; text-align: left;
251
+ }
252
+ .acao-linha.abre:hover { background: var(--hover); color: var(--texto-2); }
253
+ .acao-linha:not(.abre) { cursor: default; }
254
+ .acao-linha .ic { width: 16px; height: 16px; }
255
+ .acao-texto { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
256
+ .acao-texto b { font-weight: 500; color: var(--texto-2); }
257
+ .acao-meta { flex: none; font-variant-numeric: tabular-nums; display: inline-flex; gap: 6px; }
258
+ .acao .mais { color: var(--mais-linha); }
259
+ .acao .menos { color: var(--menos-linha); }
260
+ .acao .ok { color: var(--mais-linha); }
261
+ .acao .falhou { color: var(--aviso); }
262
+ .acao .rodando { width: 10px; height: 10px; border-radius: 50%; border: 1.5px solid var(--mais-fraco); border-top-color: var(--texto-2); animation: gira 0.8s linear infinite; }
263
+ .acao-seta { width: 14px; height: 14px; transition: transform 0.15s; opacity: 0; }
264
+ .acao-linha.abre .acao-seta { opacity: 0.8; }
265
+ .acao.aberta .acao-seta { transform: rotate(180deg); }
266
+ .acao-detalhe {
267
+ margin: 2px 0 8px 24px; padding: 10px 12px; max-height: 280px; overflow: auto;
268
+ background: var(--codigo); border: 1px solid var(--borda); border-radius: 9px;
269
+ font: 12px/1.55 var(--mono); color: var(--texto-2); white-space: pre;
270
+ }
271
+ .acao-detalhe .l-mais { color: var(--mais-linha); }
272
+ .acao-detalhe .l-menos { color: var(--menos-linha); }
273
+ .acao.fundo { padding-left: 18px; }
274
+
275
+ .saida-comando {
276
+ margin: 0; padding: 12px 14px; background: var(--codigo); border: 1px solid var(--borda);
277
+ border-radius: 10px; overflow-x: auto; font: 12.5px/1.55 var(--mono); color: var(--texto-2); white-space: pre-wrap;
278
+ }
279
+
280
+ .trabalhando { display: flex; align-items: center; gap: 10px; color: var(--fraco); font-size: 14px; }
281
+ .trabalhando .pulso {
282
+ width: 8px; height: 8px; border-radius: 50%; background: var(--marca);
283
+ animation: pulsa 1.2s ease-in-out infinite;
284
+ }
285
+ .brilho {
286
+ background: linear-gradient(90deg, var(--fraco) 0%, var(--texto) 50%, var(--fraco) 100%);
287
+ background-size: 200% 100%; -webkit-background-clip: text; background-clip: text; color: transparent;
288
+ animation: brilha 1.8s linear infinite;
289
+ }
290
+ @keyframes pulsa { 50% { opacity: 0.35; transform: scale(0.8); } }
291
+ @keyframes brilha { to { background-position: -200% 0; } }
292
+ @keyframes gira { to { transform: rotate(360deg); } }
293
+
294
+ /* ── o terminal ────────────────────────────────────────────────────────── */
295
+
296
+ .terminal { flex: 1; min-height: 0; display: flex; flex-direction: column; padding: 48px 24px 12px; }
297
+ .terminal-topo { display: flex; align-items: center; justify-content: space-between; padding-bottom: 10px; }
298
+ .terminal-topo small { color: var(--fraco); font-size: 12.5px; margin-left: 6px; }
299
+ .terminal-saida {
300
+ flex: 1; margin: 0; padding: 14px 16px; overflow: auto;
301
+ background: #0d0d0d; color: #d4d4d4; border: 1px solid var(--borda); border-radius: 12px;
302
+ font: 12.5px/1.5 var(--mono); white-space: pre-wrap; overflow-wrap: anywhere;
303
+ }
304
+ /* As cores de terminal: as mesmas do PALETTE de lib/ui.js (cubo de 256),
305
+ no fundo escuro fixo do terminal — por isso literais, não tokens. */
306
+ .c45 { color: #22d3ee; } .c31 { color: #0891b2; } .c254 { color: #e2e8f0; }
307
+ .c247 { color: #94a3b8; } .c243 { color: #64748b; } .c214 { color: #fbbf24; } .c204 { color: #fb7185; }
308
+ .forte { font-weight: 700; }
309
+
310
+ /* ── o compositor ─────────────────────────────────────────────────────── */
311
+
312
+ .rodape { flex: none; padding: 0 24px 16px; }
313
+ .compositor-zona { width: 100%; max-width: var(--largura-conversa); margin: 0 auto; }
314
+ .projeto-barra {
315
+ margin: 0 14px; height: 40px; padding: 0 16px 8px; display: flex; align-items: center;
316
+ background: var(--barra-projeto); border: 1px solid var(--borda); border-bottom: 0;
317
+ border-radius: 16px 16px 0 0; margin-bottom: -8px; box-sizing: content-box; padding-top: 0;
318
+ }
319
+ .projeto-btn { display: inline-flex; align-items: center; gap: 9px; color: var(--fraco); font-size: 14px; height: 30px; padding: 0 6px; margin-left: -6px; border-radius: 7px; }
320
+ .projeto-btn:hover { color: var(--texto); background: var(--hover); }
321
+ .projeto-btn .ic { width: 17px; height: 17px; }
322
+ .projeto-btn.tem { color: var(--texto-2); }
323
+
324
+ .compositor {
325
+ position: relative; background: var(--compositor); border: 1px solid var(--borda);
326
+ border-radius: 20px; padding: 13px 12px 10px 14px;
327
+ display: flex; flex-direction: column; gap: 10px;
328
+ box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2);
329
+ container-type: inline-size;
330
+ }
331
+ /* Compositor apertado (painel aberto, janela estreita): o nome técnico do
332
+ esforço sai primeiro, depois o texto da permissão — os ícones ficam. */
333
+ @container (max-width: 560px) { #esforcoNome { display: none; } }
334
+ @container (max-width: 420px) { .chip-perm span { display: none; } }
335
+ .compositor textarea {
336
+ width: 100%; min-height: 44px; max-height: 40vh; resize: none; border: 0; outline: 0;
337
+ background: transparent; color: var(--texto); font: 15px/1.5 var(--fonte); padding: 0 2px;
338
+ }
339
+ .compositor textarea::placeholder { color: var(--mais-fraco); }
340
+ .controles { display: flex; align-items: center; gap: 6px; min-width: 0; }
341
+ .controles > * { flex: none; }
342
+ .controles > .espaco { flex: 1; }
343
+ .controles > .icone-btn:first-child { margin-left: -3px; color: var(--texto-2); }
344
+
345
+ .chip-perm {
346
+ flex: 0 1 auto !important; min-width: 0; overflow: hidden;
347
+ display: inline-flex; align-items: center; gap: 7px; height: 30px; padding: 0 8px; border-radius: 8px;
348
+ color: var(--fraco); font-size: 14px; margin-left: 6px; white-space: nowrap;
349
+ }
350
+ .chip-perm:hover { background: var(--hover); }
351
+ .chip-perm .ic { width: 17px; height: 17px; }
352
+ .chip-perm span { overflow: hidden; text-overflow: ellipsis; }
353
+ .chip-perm[data-modo="livre"] { color: var(--laranja); }
354
+
355
+ .seletor {
356
+ display: inline-flex; align-items: center; gap: 6px; height: 30px; padding: 0 8px; border-radius: 8px;
357
+ color: var(--fraco); font-size: 14px; white-space: nowrap;
358
+ }
359
+ .seletor b { font-weight: 500; color: var(--texto-2); }
360
+ .seletor:hover { background: var(--hover); }
361
+
200
362
  .enviar {
201
- flex: 0 0 auto; width: 34px; height: 34px; border-radius: 10px; cursor: pointer;
202
- display: grid; place-items: center; border: 0;
203
- background: var(--azul); color: #04252c; transition: background .16s, opacity .16s;
204
- }
205
- html[data-tema="claro"] .enviar { color: #fff; }
206
- .enviar:disabled { background: #16323d; color: #3f6472; cursor: default; }
207
- .enviar.parar { background: rgba(251, 113, 133, .14); color: var(--falha); }
208
-
209
- /* ── configurações ──────────────────────────────────────────────────── */
210
- dialog {
211
- border: 1px solid var(--borda-viva); border-radius: 14px; padding: 0;
212
- background: var(--painel); color: var(--texto); max-width: 440px; width: calc(100% - 32px);
213
- }
214
- dialog::backdrop { background: rgba(4, 8, 12, .62); }
215
- .dlg-topo { display: flex; align-items: center; justify-content: space-between; gap: 12px;
216
- padding: 14px 17px; border-bottom: 1px solid var(--borda); }
217
- .dlg-topo h2 { margin: 0; font-size: 15.5px; font-weight: 620; }
218
- .dlg-corpo { padding: 15px 17px 19px; display: flex; flex-direction: column; gap: 19px; }
219
- .grupo > h3 { margin: 0 0 9px; font-size: 11px; letter-spacing: .08em;
220
- text-transform: uppercase; color: var(--apagado); font-weight: 500; }
221
- .opcoes { display: flex; gap: 8px; flex-wrap: wrap; }
222
- .opcao, .copiar {
223
- padding: 7px 14px; border-radius: 8px; cursor: pointer; font: inherit; font-size: 13px;
224
- border: 1px solid var(--borda-viva); background: none; color: var(--fraco);
225
- }
226
- .opcao[aria-pressed="true"] { border-color: var(--azul); color: var(--texto); }
227
- .copiar { padding: 4px 10px; font-size: 12px; }
228
- .cores { display: flex; gap: 10px; }
229
- .cor { width: 30px; height: 30px; border-radius: 50%; border: 2px solid transparent; cursor: pointer; }
230
- .cor[aria-pressed="true"] { border-color: var(--texto); }
231
- .linha-info { display: flex; justify-content: space-between; gap: 12px; font-size: 13.5px; color: var(--fraco); }
232
- .linha-info b { color: var(--texto); font-weight: 500; }
233
- .dlg-corpo code { font-family: var(--mono); color: var(--azul); }
234
-
235
- /* ── conversa ───────────────────────────────────────────────────────────── */
236
-
237
- #rolo { overflow-y: auto; scroll-behavior: smooth; }
238
- #rolo::-webkit-scrollbar { width: 10px; }
239
- #rolo::-webkit-scrollbar-thumb { background: #1c2836; border-radius: 8px; border: 3px solid var(--fundo); }
240
-
241
- #conversa { max-width: 860px; margin: 0 auto; padding: 26px 22px 40px; }
242
-
243
- /* O que o usuário disse: bolha à direita, curta, com a marca de lado. */
244
- .voce {
245
- margin: 24px 0 14px; display: flex; justify-content: flex-end;
246
- }
247
- .voce > div {
248
- background: linear-gradient(180deg, rgba(34,211,238,.12), rgba(34,211,238,.07));
249
- border: 1px solid rgba(34, 211, 238, .28);
250
- border-radius: 14px 14px 4px 14px;
251
- padding: 10px 15px; max-width: 78%;
252
- white-space: pre-wrap; word-break: break-word; line-height: 1.55;
253
- }
254
-
255
- /* A saída do agente: monoespaçada, como no terminal, porque É a saída do
256
- terminal — as mesmas linhas, as mesmas cores. */
257
- .saida {
258
- font-family: var(--mono); font-size: 12.8px; line-height: 1.62;
259
- white-space: pre-wrap; word-break: break-word;
260
- color: var(--texto); margin: 0;
261
- }
262
- .saida a { color: var(--azul); }
263
-
264
- /* As cores ANSI, traduzidas. Os números são os do lib/ui.js. */
265
- .c45 { color: var(--azul); }
266
- .c31 { color: var(--azul-fundo); }
267
- .c254 { color: var(--texto); }
268
- .c247 { color: var(--fraco); }
269
- .c243 { color: var(--apagado); }
270
- .c214 { color: var(--alerta); }
271
- .c204 { color: var(--falha); }
272
- .forte { font-weight: 650; }
273
-
274
- .aviso-erro {
275
- margin: 14px 0; padding: 10px 14px; line-height: 1.55;
276
- color: var(--falha); background: rgba(251, 113, 133, .08);
277
- border: 1px solid rgba(251, 113, 133, .26); border-radius: 10px;
278
- }
279
-
280
- /* ── arrastar arquivo ───────────────────────────────────────────────────── */
281
-
282
- #alvo-solto {
283
- position: fixed; inset: 0; display: none; place-items: center;
284
- background: rgba(6, 10, 16, .82); backdrop-filter: blur(3px); z-index: 40;
285
- }
286
- body.soltando #alvo-solto { display: grid; }
287
- #alvo-solto > div {
288
- border: 2px dashed rgba(34, 211, 238, .55); border-radius: 18px;
289
- padding: 44px 62px; text-align: center; color: var(--azul);
290
- display: grid; gap: 6px;
291
- }
292
- #alvo-solto span { color: var(--fraco); font-size: 13px; }
293
-
294
- @media (max-width: 760px) {
295
- /* Janela estreita: a barra lateral sai da frente. O botão de novo chat e o
296
- histórico continuam alcançáveis pelo terminal (/rc de novo, /conversas). */
297
- .lado { display: none; }
298
- .tira, .caixa { max-width: none; }
363
+ width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center; margin-left: 2px;
364
+ background: var(--marca); color: var(--marca-texto);
365
+ }
366
+ .enviar .ic { width: 17px; height: 17px; stroke-width: 2; }
367
+ .enviar:disabled { background: var(--enviar-off); color: var(--enviar-off-texto); cursor: default; }
368
+ .enviar.parar { background: var(--texto); color: var(--fundo); }
369
+
370
+ .anexos { display: flex; flex-wrap: wrap; gap: 6px; }
371
+ .anexo {
372
+ display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 6px 0 9px;
373
+ background: var(--hover); border: 1px solid var(--borda); border-radius: 8px; font-size: 13px; color: var(--texto-2);
374
+ }
375
+ .anexo .ic { width: 14px; height: 14px; }
376
+ .anexo button { display: grid; place-items: center; width: 18px; height: 18px; border-radius: 5px; color: var(--fraco); }
377
+ .anexo button:hover { background: var(--hover); color: var(--texto); }
378
+
379
+ /* ── o menu flutuante ─────────────────────────────────────────────────── */
380
+
381
+ .menu {
382
+ position: fixed; z-index: 20; min-width: 230px; max-width: 340px; max-height: 60vh; overflow-y: auto;
383
+ background: var(--menu); border-radius: 12px; box-shadow: var(--sombra); padding: 5px;
299
384
  }
385
+ .menu-titulo { color: var(--fraco); font-size: 12px; padding: 7px 10px 4px; }
386
+ .menu-item {
387
+ display: flex; align-items: flex-start; gap: 10px; width: 100%; padding: 7px 10px; border-radius: 8px; text-align: left;
388
+ }
389
+ .menu-item:hover, .menu-item:focus-visible { background: var(--hover); outline: 0; }
390
+ .menu-item .ic { width: 16px; height: 16px; margin-top: 1px; color: var(--fraco); }
391
+ .menu-item .rot { flex: 1; min-width: 0; }
392
+ .menu-item .rot span { display: block; color: var(--fraco); font-size: 12.5px; margin-top: 1px; }
393
+ .menu-item .marcado { color: var(--marca); font-size: 13px; }
394
+ .menu-item.laranja, .menu-item.laranja .ic { color: var(--laranja); }
395
+ .menu-sep { height: 1px; background: var(--borda); margin: 5px 4px; }
396
+ .menu-entrada { display: flex; gap: 6px; padding: 6px; }
397
+ .menu-entrada input {
398
+ flex: 1; min-width: 0; height: 30px; padding: 0 9px; font: inherit; color: var(--texto);
399
+ background: var(--fundo); border: 1px solid var(--borda-forte); border-radius: 7px;
400
+ }
401
+ .menu-entrada button { padding: 0 10px; border-radius: 7px; background: var(--ativo); }
402
+
403
+ /* ── o painel da direita ─────────────────────────────────────────────── */
404
+
405
+ .painel {
406
+ width: var(--largura-painel); min-width: 340px; max-width: 760px; flex: none;
407
+ display: flex; flex-direction: column; border-left: 1px solid var(--borda); background: var(--fundo);
408
+ }
409
+ .painel-topo { height: 42px; display: flex; align-items: center; gap: 4px; padding: 0 8px 0 10px; border-bottom: 1px solid var(--borda); }
410
+ .abas { display: flex; gap: 2px; }
411
+ .aba { height: 28px; padding: 0 11px; border-radius: 7px; color: var(--fraco); }
412
+ .aba:hover { color: var(--texto); }
413
+ .aba[aria-selected="true"] { background: var(--ativo); color: var(--texto); }
414
+ .painel-corpo { flex: 1; min-height: 0; position: relative; display: flex; }
415
+ .previa { flex: 1; border: 0; background: #fff; width: 100%; }
416
+ .painel-vazio {
417
+ position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center;
418
+ gap: 4px; padding: 24px; text-align: center; background: var(--fundo);
419
+ }
420
+ .painel-vazio p { margin: 0; max-width: 34ch; }
421
+ .painel-vazio .mascote { margin-bottom: 10px; }
422
+ .arquivos { display: grid; grid-template-rows: minmax(120px, 40%) 1fr; }
423
+ .arvore { overflow: auto; padding: 8px 6px; border-bottom: 1px solid var(--borda); font-size: 13px; }
424
+ .no {
425
+ display: flex; align-items: center; gap: 6px; width: 100%; height: 26px; padding-right: 8px; border-radius: 6px;
426
+ text-align: left; color: var(--texto-2); white-space: nowrap;
427
+ }
428
+ .no:hover { background: var(--hover); }
429
+ .no[aria-selected="true"] { background: var(--ativo); color: var(--texto); }
430
+ .no .ic { width: 15px; height: 15px; color: var(--fraco); }
431
+ .no .nome { overflow: hidden; text-overflow: ellipsis; }
432
+ .no.mudou .nome::after { content: " •"; color: var(--marca); }
433
+ .visor { display: flex; flex-direction: column; min-height: 0; }
434
+ .visor-topo { padding: 8px 14px; color: var(--fraco); font-size: 12.5px; border-bottom: 1px solid var(--borda); font-family: var(--mono); }
435
+ .visor-texto { flex: 1; margin: 0; padding: 10px 0; overflow: auto; font: 12px/1.6 var(--mono); color: var(--texto-2); counter-reset: l; }
436
+ .visor-texto .ln { display: block; padding: 0 14px 0 0; white-space: pre; }
437
+ .visor-texto .ln::before {
438
+ counter-increment: l; content: counter(l); display: inline-block; width: 3.4em; margin-right: 12px;
439
+ text-align: right; color: var(--mais-fraco); user-select: none;
440
+ }
441
+
442
+ /* ── diálogo ──────────────────────────────────────────────────────────── */
443
+
444
+ .dialogo {
445
+ width: min(520px, calc(100vw - 32px)); padding: 0; border: 0; border-radius: 14px;
446
+ background: var(--menu); color: var(--texto); box-shadow: var(--sombra);
447
+ }
448
+ .dialogo::backdrop { background: rgba(0, 0, 0, 0.5); }
449
+ .dlg-topo { display: flex; align-items: center; justify-content: space-between; padding: 14px 14px 4px 20px; }
450
+ .dlg-topo h2 { margin: 0; font-size: 16px; font-weight: 600; }
451
+ .dlg-corpo { padding: 4px 20px 20px; }
452
+ .dlg-corpo h3 { font-size: 12.5px; font-weight: 500; color: var(--fraco); margin: 14px 0 8px; }
453
+ .dlg-corpo p { margin: 0 0 8px; font-size: 13px; }
454
+ .atalhos { display: grid; grid-template-columns: max-content 1fr; gap: 8px 16px; margin: 0; align-items: center; }
455
+ .atalhos dd { margin: 0; color: var(--texto-2); }
456
+ kbd {
457
+ font: 12px var(--mono); padding: 2px 6px; border-radius: 5px; background: var(--hover);
458
+ border: 1px solid var(--borda-forte); color: var(--texto-2);
459
+ }
460
+ .comandos { display: grid; grid-template-columns: 1fr 1fr; gap: 4px; }
461
+ .comandos button { text-align: left; padding: 7px 10px; border-radius: 8px; font-family: var(--mono); font-size: 13px; }
462
+ .comandos button:hover { background: var(--hover); }
463
+ .comandos span { display: block; font-family: var(--fonte); color: var(--fraco); font-size: 12px; }
464
+
465
+ /* ── soltar arquivo ───────────────────────────────────────────────────── */
466
+
467
+ .alvo-solto {
468
+ position: fixed; inset: 0; z-index: 30; display: none; place-items: center;
469
+ background: rgba(0, 0, 0, 0.45); pointer-events: none;
470
+ }
471
+ body.soltando .alvo-solto { display: grid; }
472
+ .alvo-solto > div {
473
+ display: flex; flex-direction: column; gap: 4px; align-items: center; padding: 28px 40px;
474
+ border: 1.5px dashed var(--marca); border-radius: 18px; background: var(--menu);
475
+ }
476
+ .alvo-solto span { color: var(--fraco); }
477
+
478
+ /* ── telas estreitas ──────────────────────────────────────────────────
479
+ Abaixo de 1100px o painel não cabe ao lado da conversa e passa a flutuar
480
+ por cima; abaixo de 960px a barra lateral também, e começa recolhida. */
481
+ @media (max-width: 960px) {
482
+ .lado { position: absolute; z-index: 10; top: 0; bottom: 0; left: 0; box-shadow: var(--sombra); }
483
+ }
484
+ @media (max-width: 1100px) {
485
+ .painel { position: absolute; z-index: 9; top: 0; bottom: 0; right: 0; width: min(560px, 92vw); min-width: 0; box-shadow: var(--sombra); }
486
+ }
487
+ @media (max-width: 640px) {
488
+ .rodape { padding: 0 12px 12px; }
489
+ .chat { padding-left: 14px; padding-right: 14px; }
490
+ .chip-perm span, .seletor span { display: none; }
491
+ .comandos { grid-template-columns: 1fr; }
492
+ }
493
+ @media (prefers-reduced-motion: reduce) {
494
+ *, *::before, *::after { animation: none !important; transition: none !important; }
495
+ }
496
+
497
+ /* A saída de um comando também aparece no chat, sobre o fundo de código do
498
+ tema — no claro, o "branco de terminal" sumiria. */
499
+ :root[data-tema="claro"] .saida-comando .c254 { color: var(--texto); }
500
+ :root[data-tema="claro"] .saida-comando .c247 { color: var(--fraco); }