sagadeck 1.8.0 → 1.9.0

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 (92) hide show
  1. package/README.md +19 -8
  2. package/SKILL.md +10 -3
  3. package/bin/sagadeck.js +23 -0
  4. package/docs/ANDAMENTO.md +367 -7
  5. package/docs/PLANO-MELHORIAS.md +180 -0
  6. package/docs/REFERENCIA.md +131 -110
  7. package/package.json +33 -2
  8. package/src/ai/commands.js +2 -2
  9. package/src/ai/deck-ai.js +1 -1
  10. package/src/ai/ia-check.js +127 -0
  11. package/src/ai/ia-config.js +2 -2
  12. package/src/ai/llm.js +5 -1
  13. package/src/ai/map-analysis-run.js +1 -1
  14. package/src/ai/quality.js +1 -1
  15. package/src/ai/video-generation.js +70 -25
  16. package/src/build.js +46 -14
  17. package/src/elements.js +39 -1
  18. package/src/export/pptx.js +7 -2
  19. package/src/export/shots.js +7 -2
  20. package/src/fiscal/normalize.js +19 -0
  21. package/src/fs-retry.js +37 -2
  22. package/src/import/office.js +5 -4
  23. package/src/layouts.js +104 -99
  24. package/src/lessons.js +1 -1
  25. package/src/library.js +7 -7
  26. package/src/map-analysis.js +4 -1
  27. package/src/map-config.js +10 -4
  28. package/src/map.js +21 -8
  29. package/src/mcp/server.js +17 -0
  30. package/src/motion.js +20 -6
  31. package/src/purpose.js +1 -1
  32. package/src/runtime/base.css +88 -332
  33. package/src/runtime/fit.js +3 -2
  34. package/src/runtime/fonts/amatic-sc.css +3 -0
  35. package/src/runtime/fonts/bebas-neue.css +2 -0
  36. package/src/runtime/fonts/cabin-sketch.css +2 -0
  37. package/src/runtime/fonts/fraunces.css +3 -0
  38. package/src/runtime/fonts/gelasio.css +3 -0
  39. package/src/runtime/fonts/ibm-plex-mono.css +4 -0
  40. package/src/runtime/fonts/index.json +10 -1
  41. package/src/runtime/fonts/itim.css +2 -0
  42. package/src/runtime/fonts/montserrat.css +2 -0
  43. package/src/runtime/fonts/space-grotesk.css +2 -0
  44. package/src/runtime/map-background.js +91 -0
  45. package/src/runtime/map.js +41 -9
  46. package/src/runtime/runtime.js +81 -100
  47. package/src/runtime/skins/caderno.css +33 -0
  48. package/src/runtime/skins/cartaz.css +27 -0
  49. package/src/runtime/skins/infografico.css +29 -0
  50. package/src/runtime/skins/lousa.css +22 -0
  51. package/src/runtime/skins/musgo.css +42 -0
  52. package/src/runtime/vendor/MAPLIBRE-LEAFLET-LICENSE.txt +15 -0
  53. package/src/runtime/vendor/MAPLIBRE-LICENSE.txt +116 -0
  54. package/src/runtime/vendor/geo-contornos.json +1 -1
  55. package/src/runtime/vendor/maplibre-gl.css +1 -0
  56. package/src/runtime/vendor/maplibre-gl.js +825 -0
  57. package/src/runtime/vendor/maplibre-leaflet.js +234 -0
  58. package/src/runtime/vendor/maplibre-worker.js +10 -0
  59. package/src/studio/assets/imagens/tour-mapa-botao.jpg +0 -0
  60. package/src/studio/assets/imagens/tour-mapa-editor.jpg +0 -0
  61. package/src/studio/command-approval.js +2 -3
  62. package/src/studio/demo-decks.js +4 -2
  63. package/src/studio/export-jobs.js +86 -0
  64. package/src/studio/exporting.js +36 -18
  65. package/src/studio/feature-demos.js +144 -0
  66. package/src/studio/ia-routes.js +9 -0
  67. package/src/studio/layout-samples.js +9 -18
  68. package/src/studio/library-routes.js +0 -9
  69. package/src/studio/project.js +1 -0
  70. package/src/studio/public/ai-settings.js +2 -2
  71. package/src/studio/public/app.js +41 -51
  72. package/src/studio/public/export-status.js +154 -0
  73. package/src/studio/public/index.html +13 -10
  74. package/src/studio/public/library.css +12 -3
  75. package/src/studio/public/library.html +1 -0
  76. package/src/studio/public/library.js +36 -14
  77. package/src/studio/public/map-data.js +7 -3
  78. package/src/studio/public/map-editor.js +625 -236
  79. package/src/studio/public/map-settings.js +3 -1
  80. package/src/studio/public/slide-form.js +18 -15
  81. package/src/studio/public/style.css +54 -9
  82. package/src/studio/public/ui-icons.js +1 -1
  83. package/src/studio/server.js +27 -12
  84. package/src/studio/snapshot.js +8 -4
  85. package/src/studio/template-collections.js +1 -1
  86. package/src/studio/tour.js +89 -7
  87. package/src/themes.js +154 -0
  88. package/templates/cenario-e-ciencia.yaml +1 -21
  89. package/templates/ensaio-api.yaml +3 -3
  90. package/templates/cenario/Texto no cen/303/241rio.yaml" +0 -171
  91. package/templates/cenario/imagens/cidade.svg +0 -30
  92. package/templates/cenario/imagens/pessoa.svg +0 -15
@@ -15,7 +15,7 @@ Mídia paga não é proibida por padrão. Quando for apropriada, proponha seu us
15
15
  ```yaml
16
16
  title: Nome da palestra # obrigatório (vira rodapé e título da janela)
17
17
  author: Seu Nome · Cargo
18
- theme: sinal # sinal | editorial | noite | bauhaus | terminal | jornal | rabisco | oceano | pop | aurora | prata | aluminio | arcade | relevo (ou customizado, ver fim)
18
+ theme: sinal # sinal | editorial | noite | bauhaus | terminal | jornal | rabisco | oceano | pop | aurora | prata | aluminio | arcade | relevo | musgo | wine | caderno | lousa | cartaz | infografico (ou customizado, ver fim)
19
19
  palette: floresta # opcional: só as cores, vale em qualquer tema (ver "Temas e paletas"); sem ela, as cores do tema
20
20
  duration: 50 # minutos — o modo apresentador mostra se você está adiantado/atrasado
21
21
  event: Summit de Dados 2026 # opcional — para {evento} no rodapé/cabeçalho
@@ -60,7 +60,8 @@ slides:
60
60
  | `background` | figura de fundo atrás do conteúdo |
61
61
  | `bg` / `fg` | cor de fundo / texto (hex) só neste slide |
62
62
  | `transition` | `fade` (padrão), `cut` (seca), `saida` (o anterior recua e dissolve, o próximo entra de baixo) ou `morph` (crossfade longo com respiro de escala; combine com `continuity:` nos elementos que continuam) — só no HTML; PPTX/PDF usam o quadro final |
63
- | `ambient` | eco ambiente nos slides estáticos: `pontos` (poeira de luz à deriva) ou `grade` (grade em perspectiva deslizando) — lembra a capa sem repeti-la; parado com movimento reduzido ou na exportação |
63
+ | `ambient` | eco ambiente nos slides estáticos: `pontos` (poeira de luz à deriva), `grade` (grade em perspectiva deslizando) ou `rede` (nós à deriva que se ligam por linhas finas quando se aproximam, na cor de destaque; no tema `musgo` ela já vem atrás da capa, e `ambient: false` tira) — lembra a capa sem repeti-la; parado com movimento reduzido ou na exportação |
64
+ | `ticker` | só na capa: faixa que corre devagar no pé, com os itens separados por losangos (`ticker: [Pesquisa, Arquitetura, Plano]`). No tema `musgo` ela vem sozinha, com os títulos das seções; `ticker: false` tira. Para no mouse; parada com movimento reduzido, `motion: none` e na exportação (só no HTML) |
64
65
  | `footer: false` | esconde o rodapé neste slide |
65
66
  | `id` | nome curto do slide, destino dos links (`goto`, `back`, `next`, `[texto](#id)`); ver [Navegação por caminhos](#navegação-por-caminhos-hub-goto-back-next) |
66
67
  | `back` | id (ou número) do slide para onde o botão **Voltar** do canto leva; o botão mostra o título do destino |
@@ -81,19 +82,19 @@ Tabela em markdown no meio de um texto (`problem`, `body`, `text`, passo do `sol
81
82
  | `cover` | `kicker, title, subtitle, author, role, figure` | capa |
82
83
  | `section` | `number, kicker, title, subtitle, figure` | abertura de ato/capítulo (tom `accent` por padrão) |
83
84
  | `statement` | `text` **ou** `lines: [ {text, as, color, step} ]`, `by`, `center` | uma frase de impacto; `lines` + `build` revelam linha a linha |
84
- | `calendar` | `kicker, title, events: [{date, title, text, tag, color}], undated: [{title, text}], undatedTitle, cols, build` | datas num **calendário** (agenda, lançamentos, cronograma, "infográfico em forma de calendário"): um cartão por mês que tem evento, com o mini calendário do mês (os dias marcados na cor do tipo) e a lista; `date`: `2026-12-18`, `18/12/2026` ou só o mês `2026-12`; cada `tag` (Filme, Série…) ganha uma cor e entra na legenda; o que não tem data vai no cartão "sem data" (`undated`). Para "calendário", este; `timeline` é para uma sequência de marcos sem a grade dos dias |
85
+ | `calendar` | `kicker, title, events: [{date, time, title, text, tag, color}], undated: [{title, text}], undatedTitle, view, month, week, cols, build` | datas num **calendário** (agenda, lançamentos, cronograma, programação, "infográfico em forma de calendário"). `view`: `meses` (um cartão por mês com o mini calendário e a lista; poucos eventos por mês), `mes` (um mês grande, como calendário de parede, com os eventos escritos nos dias; muitos eventos num mês só), `semana` (uma coluna por dia com o horário; programação de um evento; fim de semana vazio some), `lista` (agenda compacta em colunas, agrupada por mês; muitos meses cheios). Sem `view`, o sagadeck escolhe pelo que cabe; muitos eventos em vários meses ficam melhores em **um slide por mês** (`view: mes` + `month: 2026-11` em cada slide, só com os eventos daquele mês). `week: 2026-11-16` escolhe a semana. `date`: `2026-12-18`, `18/12/2026`, `2026-12-18 14:00` ou só o mês `2026-12`; `time` ("14:00") também dá a hora; cada `tag` (Filme, Série…) ganha uma cor e entra na legenda; o que não tem data vai em "sem data" (`undated`). Para "calendário", este; `timeline` é para uma sequência de marcos sem a grade dos dias |
85
86
  | `poster` | `kicker, title, subtitle, hero` (ilustração principal: `{ image_prompt }`, imagem, gráfico…), `panels: [{label, title, text, icon` ou `figure` ou `image_prompt, facts: [{value, label}]}], flow, cols, key, build` | infográfico de UMA página no estilo de figura de revista científica (Nature, Scientific American): a ilustração principal e painéis com letra (a, b, c…), cada um com um desenho, título, texto curto e números com unidade; `flow: true` põe setas na ordem (receita, processo, protocolo); `key` é a nota de rodapé (fonte, condições). Para "infográfico de uma página", "pôster" ou "como fazer X numa página", este e não o `onepage` (que é jornada, problema e solução de um projeto). Ilustre os painéis com `image_prompt` no mesmo estilo (ex.: "clean scientific illustration, flat, white background") |
86
87
  | `definition` | `kicker, term, origin, parts: [{word, meaning}], text, icon` (ou `figure`), `build`, `termSize` (px do termo) | definição de um termo, como verbete: o termo em destaque, a origem da palavra em partes (`origin: do grego`, `parts: [{word: hydor, meaning: água}, {word: logos, meaning: ciência}]`) e a definição; para "o que é X", use este e não um `statement` com o parágrafo inteiro |
87
88
  | `quote` | `quote, by, role, after, afterStep` | citação; `after` aparece num clique |
88
89
  | `number` | `value, prefix, suffix, decimals, from, label, context, side, valueColor` | número gigante animado (conta de `from` até `value`) |
89
90
  | `split` | `title, body, bullets, content, figure, ratio: "1.2:1", reverse, build` | texto + figura |
90
- | `cards` | `title, items: [{icon, picto, number, title, text, foot, hl, goto}], cols, build` | 2–4 cartões |
91
+ | `cards` | `title, items: [{icon, picto, number, title, text, foot, hl, goto, flip}], cols, build` | 2–4 cartões; com `flip` o cartão **vira** no clique (ver abaixo) |
91
92
  | `list` | `title, items: [texto ou {text, sub, goto}], numbered, size, build` | lista numerada grande |
92
93
  | `hub` | `kicker, title, question, options: [{icon, title, text, meta, goto}], cols, build` | mapa de caminhos: cada opção leva (`goto`) à parte da apresentação daquele caminho; ver [Navegação por caminhos](#navegação-por-caminhos-hub-goto-back-next) |
93
94
  | `onepage` | `kicker, title, subtitle, journey: [texto ou {icon, title, text, goto}], journeyTitle, problem: {title, text, numbers: [{value, label}], items}, solution: {…}, dashboard: {numbers: [{value, label, trend, title}], figures: [gráfico ou ufmap, com title]}` | tudo numa página (jornada, problema, solução, painel); ver [One-page](#one-page-onepage) |
94
95
  | `status` | `kicker, title, health: ok\|risco\|atrasado, healthLabel, progress (0–100), highlight, done, doing, blocked, risks, upcoming: [texto ou {text, owner, due}], shots: [{image, caption}]` | status semanal; ver [Status semanal](#status-semanal-status) |
95
96
  | `stats` | `title, stats: [{value, label, text, icon, trend, trendUp, color}], cols, build` | indicadores (KPIs) em cartões, com tendência (`trend: "+12%"`) |
96
- | `timeline` | `title, events: [{when, title, text, tag}], highlight, after, build` | linha do tempo |
97
+ | `timeline` | `title, events: [{when, title, text, tag, more}], highlight, after, build` | linha do tempo; `more` põe um botão + no marco que abre um balão (ver abaixo) |
97
98
  | `chart` | `title, chart: {…}, side (texto ou elemento), chartHeight` | gráfico + comentário |
98
99
  | `table` | `title, head, rows, style, color, highlight, total, side, caption, source` | tabela de verdade nas cores do tema |
99
100
  | `map` | `kicker, title, basemap, layers: [{name, points \| geojson \| gpx \| kml \| areas, color, size, label, colors, popup, step, view}], build, view, caption` | **mapa ao vivo** com pontos, linhas e áreas (sensores, medidores, unidades de atendimento, cinemas, trajetos, regiões…): os dados vêm da planilha do projeto ou de arquivos GeoJSON/GPX/KML; ver [Mapa](#mapa-map) |
@@ -113,7 +114,6 @@ Tabela em markdown no meio de um texto (`problem`, `body`, `text`, passo do `sol
113
114
  | `references` | `title, items` | fontes (2 colunas) |
114
115
  | `headline` | `kicker, text, as, size, caption` | manchete: uma frase CURTA (até ~12 palavras) enorme ocupando o slide; frase longa sai menor (como no `statement`) e conta como slide de frase única (no máximo 2 por deck) |
115
116
  | `full` | `figure` (ou `image`/`image_prompt`), `kicker, title, caption, overlay: bottom\|left\|center\|none, fit, titleSize` | figura/imagem de página inteira com texto por cima; com `image_prompt` a IA gera a página toda. Figura do documento (`contexto/visuais/…`) ou `fit: contain` com texto não leva véu: sai com o título no alto, a figura inteira e a legenda embaixo (como `image`) |
116
- | `kinetic` | `figure, beats: [{text, style, position, color, size, tag}], autoplay, interval` | frases curtas em sequência sobre uma cena; avanço manual ou automático |
117
117
  | `bento` | `title, tiles: [{title, text, value, icon, figure, size: big\|wide\|tall, hl}], cols, build` | mosaico de blocos de tamanhos diferentes |
118
118
  | `funnel` | `title, stages: [{title, value, text, hl}], build` | funil que afunila etapa a etapa |
119
119
  | `pyramid` | `title, levels: [{title, text, hl}], build` | pirâmide (topo → base) |
@@ -194,37 +194,6 @@ paginação automática de apostila ainda não fazem parte deste editor.
194
194
  No YAML, um ponto usa `kind: point`, `x` e `y` em porcentagens. Áreas usam `kind: area` (ou omitem `kind`)
195
195
  e acrescentam `width` e `height`. Ambos aceitam `title` e `text` dentro de `hotspots` do layout `spotlight`.
196
196
 
197
- ## Slide `kinetic`: tipografia em cena
198
-
199
- O layout `kinetic` combina uma figura de fundo com frases curtas que entram em sequência, podendo variar
200
- estilo, posição, cor e escala em cada batida. No Studio, adicione a cena e edite cada frase; a sequência
201
- interativa roda em **Apresentar** e avança pelos botões ou automaticamente. A prévia no editor mostra
202
- apenas o primeiro quadro. Ao trocar outro layout para `kinetic`, o SagaDeck reaproveita o título ou os
203
- itens existentes como frases e mantém a figura do slide. Sem título, frase ou itens, começa com
204
- “Uma ideia em movimento”.
205
-
206
- `autoplay` é `true` por padrão para duas ou mais frases e `interval` define o tempo em milissegundos
207
- (450–5000, padrão 1000). Movimento automático começa ao entrar no slide, para ao sair ou ao chegar à
208
- última frase, e respeita a preferência do sistema por movimento reduzido; o botão ainda permite iniciar
209
- manualmente. Para uma frase estática, use `autoplay: false`.
210
-
211
- Os estilos disponíveis são `clean`, `poster`, `editorial`, `outline` e `marker`; o estilo limpo é o padrão,
212
- sem brilho ou sombra exagerada. Posições: `left`, `center`,
213
- `right`, `top` e `bottom`; cores: `white`, `gold`, `pink` e `cyan`; escalas: `small`, `medium` e `large`.
214
- Campos omitidos variam com a batida para criar ritmo visual. Em impressão/exportação estática, os controles
215
- e a animação são substituídos por uma lista das frases.
216
-
217
- ```yaml
218
- - layout: kinetic
219
- figure: { image: palco.jpg }
220
- autoplay: true
221
- interval: 1100
222
- beats:
223
- - { text: "A IDEIA", style: poster, position: left, color: white, size: large, tag: "COMEÇA PEQUENA" }
224
- - { text: "ACENDE", style: clean, position: right, color: white, size: large }
225
- - { text: "E MUDA", style: editorial, position: bottom, color: gold, size: medium }
226
- ```
227
-
228
197
  ## Slide `api`: requisição ao vivo
229
198
 
230
199
  Um slide tipo Postman: mostra o pedido (URL, corpo, cabeçalhos) e o código equivalente (curl, JavaScript,
@@ -235,8 +204,9 @@ Os pedidos saem do **Studio** (Node, na sua máquina), nunca do navegador: sem p
235
204
  certificado da empresa e com o token fora da página. Sem o Studio (HTML exportado, PDF, servidor
236
205
  multiusuário), o slide mostra a **última resposta gravada** e o botão vira *Reproduzir gravação*.
237
206
 
238
- No Studio: **Biblioteca → Nova → Exemplo: aula de APIs ao vivo** cria um deck com um slide de cada tipo;
239
- no editor, **Inserir → Slide de API** insere um deles e **Inserir → Ambientes** edita os ambientes. Os
207
+ No Studio: a demo **APIs com curl** (Demos oficiais, ou Nova → Modelo pronto) mostra as chamadas mais comuns com o curl;
208
+ o ensaio completo, com um slide de cada tipo (upload, OCR, embeddings, voz, tempo real), sai pelo comando
209
+ `sagadeck ensaio-api`. No editor, **Inserir → Slide de API** insere um deles e **Inserir → Ambientes** edita os ambientes. Os
240
210
  exemplos rodam no ambiente embutido **ENSAIO**, uma API de mentira que o Studio local sobe sozinho (não vai
241
211
  para o seu arquivo de ambientes; o seu ambiente com o mesmo nome, se existir, vence).
242
212
 
@@ -386,7 +356,7 @@ Executar só funciona no Studio **local**: escutando em `127.0.0.1`, chamado pel
386
356
 
387
357
  ## Navegação por caminhos (`hub`, `goto`, `back`, `next`)
388
358
 
389
- Para processo com vários caminhos ("é experimento ou projeto? DEV, HOM ou PROD?", "o que muda conforme o
359
+ Para conteúdo com vários caminhos ("é a primeira vez ou já usa?", "o que muda conforme o
390
360
  front-end?"), em vez de uma sequência única: um **mapa** (`layout: hub`) com as opções, cada uma levando à sua
391
361
  seção; cada seção termina voltando ao mapa. Funciona ao apresentar (clique), no PDF (links entre páginas) e no
392
362
  PowerPoint (clique pula para o slide).
@@ -404,24 +374,24 @@ PowerPoint (clique pula para o slide).
404
374
  - layout: hub
405
375
  id: mapa
406
376
  title: Qual é o seu caso?
407
- question: Cada caminho tem prazos e responsáveis diferentes
377
+ question: Cada caminho tem passos diferentes
408
378
  options:
409
- - { icon: flask-conical, title: Experimento, text: Dados fictícios, meta: 30 dias, goto: experimento }
410
- - { icon: rocket, title: Projeto, text: DEV, HOM e PROD, goto: projeto }
379
+ - { icon: user, title: Primeira vez, text: Do zero ao primeiro resultado, meta: 4 passos, goto: inicio }
380
+ - { icon: rocket, title: Já uso, text: Atalhos e automação, goto: atalhos }
411
381
  - layout: steps
412
- id: experimento
382
+ id: inicio
413
383
  back: mapa
414
- title: Experimento
415
- steps: [{ title: Pedido }, { title: 30 dias }, { title: Renovar ou virar projeto, goto: projeto }]
384
+ title: Primeira vez
385
+ steps: [{ title: Instalar }, { title: Primeiro projeto }, { title: Pronto? Veja os atalhos, goto: atalhos }]
416
386
  - layout: statement
417
- text: Passou de 30 dias? Renove ou [vire projeto](#projeto).
387
+ text: Já fez o primeiro? Conheça os [atalhos](#atalhos).
418
388
  next: mapa # fim do caminho: volta ao mapa
419
389
  - layout: cards
420
- id: projeto
390
+ id: atalhos
421
391
  back: mapa
422
392
  next: mapa
423
- title: Projeto
424
- items: [{ title: DEV, text: 30 dias }, { title: HOM, text: 30 dias }, { title: PROD, text: sem prazo }]
393
+ title: Já uso
394
+ items: [{ title: Teclado, text: sem o mouse }, { title: Modelos, text: reaproveite }, { title: Automação, text: sem cliques }]
425
395
  ```
426
396
 
427
397
  ## One-page (`onepage`)
@@ -437,23 +407,23 @@ aparece como frase curta em destaque. É denso de propósito: o limite de palavr
437
407
  ```yaml
438
408
  - layout: onepage
439
409
  kicker: Proposta
440
- title: Cadastro digital de clientes
441
- subtitle: Menos papel, menos fila, menos retrabalho
410
+ title: Agendamento online de consultas
411
+ subtitle: Menos telefone, menos espera, menos falta
442
412
  journey:
443
- - { icon: user, title: Cliente chega, text: Fila de 40 min }
444
- - { icon: file-text, title: Preenche papel, text: 3 formulários }
445
- - { icon: check, title: Conta aberta, text: Até 5 dias }
413
+ - { icon: user, title: Paciente liga, text: Espera de 15 min }
414
+ - { icon: file-text, title: Preenche a ficha, text: 3 formulários }
415
+ - { icon: check, title: Consulta marcada, text: Até 5 dias }
446
416
  problem:
447
- text: O cadastro em papel atrasa a abertura de contas.
448
- numbers: [{ value: 5 dias, label: para abrir uma conta }, { value: 20%, label: dos cadastros refeitos }]
417
+ text: Marcar por telefone atrasa as consultas.
418
+ numbers: [{ value: 5 dias, label: para marcar uma consulta }, { value: 20%, label: de faltas }]
449
419
  solution:
450
- text: Cadastro no tablet, com validação na hora e assinatura digital.
451
- items: [Conta aberta no mesmo dia, Zero papel na agência]
420
+ text: Agendamento pelo celular, com confirmação automática e lembrete.
421
+ items: [Consulta marcada no mesmo dia, Zero ligação para remarcar]
452
422
  dashboard:
453
- numbers: [{ value: 1,2 mi, label: cadastros por ano, trend: +8% }]
423
+ numbers: [{ value: 1,2 mi, label: consultas por ano, trend: +8% }]
454
424
  figures:
455
- - { title: Tempo por etapa (min), chart: bar, data: [{ label: Fila, value: 40 }, { label: Papel, value: 25 }] }
456
- - { title: Cadastros por UF (mil), ufmap: { SP: 320, RJ: 140, MG: 150, BA: 90 }, highlight: [SP] }
425
+ - { title: Tempo por etapa (min), chart: bar, data: [{ label: Telefone, value: 15 }, { label: Ficha, value: 10 }] }
426
+ - { title: Consultas por UF (mil), ufmap: { SP: 320, RJ: 140, MG: 150, BA: 90 }, highlight: [SP] }
457
427
  ```
458
428
 
459
429
  ## Status semanal (`status`)
@@ -471,15 +441,29 @@ status por projeto, um slide `status` para cada.
471
441
  title: Portal do cliente
472
442
  health: risco
473
443
  progress: 65
474
- highlight: Login novo em homologação
444
+ highlight: Login novo em teste com usuários
475
445
  done: [Tela de login, { text: Integração com o cadastro, owner: Ana }]
476
446
  doing: [Recuperação de senha]
477
- blocked: [{ text: Liberação de firewall, owner: Infra, due: 30/09 }]
478
- risks: [Prazo de HOM apertado]
479
- upcoming: [Homologar com o negócio]
447
+ blocked: [{ text: Aprovação do texto de privacidade, owner: Jurídico, due: 30/09 }]
448
+ risks: [Prazo do teste apertado]
449
+ upcoming: [Teste com 20 usuários]
480
450
  shots: [{ image: imagens/login.png, caption: Nova tela de login }]
481
451
  ```
482
452
 
453
+ ### Cartão que vira e botão + (interatividade de infográfico)
454
+
455
+ Cartão com `flip` gira no clique e mostra o verso: `flip: "texto"` ou `flip: { title: "Clique, descubra", text: "…" }` (ou `flipTitle`). (Não confunda com `back`, o botão Voltar da navegação.) Um ícone de girar no canto avisa que vira; Enter/Espaço também viram; sair do slide desvira. Use para a ideia principal na frente e o detalhe, o exemplo ou a pista no verso — a plateia descobre explorando. No PDF e no PPTX sai a frente (ponha o verso nas notas se ele precisar aparecer impresso).
456
+
457
+ ```yaml
458
+ - layout: cards
459
+ title: Três movimentos
460
+ items:
461
+ - { icon: clock, title: Visualizar ideias, flip: "Desenhe antes de escrever." }
462
+ - { icon: bar-chart-3, title: Ativar a experiência, flip: { title: "Clique, descubra", text: "Os detalhes ficam para quem explora." } }
463
+ ```
464
+
465
+ O botão + (`more` no marco da linha do tempo, ou o elemento `pop` em qualquer lugar) faz o mesmo papel para pontos soltos: o detalhe fica guardado até alguém clicar.
466
+
483
467
  ## Elementos (dentro de `content`, `side`, `add`, `figure`, `elements`…)
484
468
 
485
469
  Todo elemento aceita: `step` (clique em que aparece), `exit` (clique em que some), `anim` (`up` padrão, `fade`, `pop`, `left`, `right`, `down`, `zoom`, `none`), `w`, `h`, `flex`, `color`, `bg`, `align`, `pad`, `card: true|hi`, `class`, `style` e, no `canvas`, `x`, `y`.
@@ -498,6 +482,7 @@ Todo elemento aceita: `step` (clique em que aparece), `exit` (clique em que some
498
482
  | pontos | `{ points: fone }` ou `{ points: { de: fone, para: mic, legenda: "Ouvindo", legendaPara: "Agindo" } }` — ícone desenhado com luzinhas que viajam de uma forma a outra no clique (só no HTML; PPTX/PDF usam a inicial). Formas: `fone`, `mic`, `doc`, `planilha`, `busca`, `chat` |
499
483
  | forma | `{ shape: rect|rounded|circle|pill|line|triangle|diamond|hexagon|star|arrow|chevron|bubble, fill: hi, stroke: fg, strokeWidth, w, h, content }` (circle vira elipse se w ≠ h; triangle…bubble são desenhos com preenchimento e contorno) |
500
484
  | selo | `{ badge: "NOVO" }` |
485
+ | botão + com balão | `{ pop: { title: "Planejar", text: "Estruture antes de desenhar.", side: above }, x: 1400, y: 300 }` (atalho: `{ pop: "texto" }`) — botão redondo com +; o clique abre um balãozinho com título e texto e escurece o resto do slide; clicar de novo, fora ou trocar de slide fecha. `side`: `above` (padrão), `below`, `left`, `right`. Bom em cima de mapa, foto ou diagrama (ponto a explorar); fechado no PDF e no PPTX |
501
486
  | aviso | `{ aviso: { tipo: dica, titulo: "Dica", texto: "…" } }` — tipos: `importante`, `atencao`, `dica`, `perigo` (atalho: `{ aviso: "texto" }` vira dica). Caixa com ícone e cor do tema para o que não pode passar batido; slide denso fecha com 1 takeaway em ==destaque== mais um aviso quando couber |
502
487
  | vídeo | `{ video: "https://…", label: "Assistir" }` · loop silencioso de fundo/detalhe: `{ video: cena.mp4, loop: true, poster: capa.jpg }` (repete sozinho, sem controles; PPTX/PDF usam o `poster` ou o primeiro quadro) |
503
488
  | HTML livre | `{ html: "<div>…</div>" }` |
@@ -564,8 +549,8 @@ Linhas que começam com PALAVRAS EM MAIÚSCULAS seguidas de `:` viram etiquetas
564
549
 
565
550
  Como no PowerPoint, são duas escolhas independentes:
566
551
 
567
- - **Tema** (`theme`): fontes, raio das bordas, textura e uma **pele** própria que rearruma capa, seção e encerramento, muda o jeito dos slides de conteúdo (título, cartões, marcadores da lista, citação, número grande, frase) e põe ornamentos (`sinal`: faixa zebrada e selo no chapéu; `editorial`: fios e capa centralizada; `noite`: moldura fina; `bauhaus`: círculo, quadrado e triângulo; `terminal`: janela com barra e prompt; `jornal`: fios de jornal e manchete sublinhada; `rabisco`: fitas adesivas e títulos inclinados; `oceano`: ondas e chapéu em pílula; `pop`: adesivos e sombra chapada; `aurora`: brilhos e traço em gradiente; `prata`: limpo e centralizado; `relevo`: ficção científica sóbria (sala de controle de filme, sem néon): grafite profundo, curvas de nível ao fundo, cantoneiras de mira, título leve embaixo à esquerda, rótulos técnicos em monoespaçada; combina com ilustração 3D realista (terreno, cidade, água) e gráfico 3D (`science` com superfície); `arcade`: videogame e fliperama, tela de tubo com linhas de varredura, neon, título em pixel no meio e chão de tijolos de jogo de plataforma; `aluminio`: prata metálico de lançamento de aparelho premium, título cromado embaixo à esquerda e um disco de metal polido; `manual` e `manual-noite`: documentação técnica, sem ornamento, código e texto corrido legíveis — o par claro/escuro do mesmo arranjo, para material de consulta, tutorial e apostila: `manual` imprime bem, `manual-noite` descansa a vista). Nos slides de conteúdo: `sinal` barra de aviso e placas; `editorial` fios finos e citação centralizada; `noite` tudo centralizado e cartões vazados; `bauhaus` faixas de cor primária e círculos; `terminal` título como comando e cartões-janela; `jornal` fios duplos e colunas; `oceano` cartões flutuando e balões; `pop` contorno grosso e sombra dura; `prata` centralizado e sem caixa; `aluminio` cartões de alumínio com chanfro de luz; `relevo` painéis de vidro fosco com traço gelo; `arcade` cartões de 8 bits com borda de pixel e sombra dura; `rabisco` tracejados e números circulados; `aurora` vidro com brilho. Trocar o tema já muda o arranjo: não reescreva slides só para "combinar" com o tema.
568
- - **Paleta** (`palette`): só as cores, em qualquer tema. `tinta`, `floresta`, `mar`, `entardecer`, `lavanda`, `grafite`, `neon`, `areia`, `cereja`, `corporativo`, `luzquente`, ou as suas: `palette: { paper: "F4F1EA", ink: "161616", accent: "D7263D", alert: "1B998B" }`. Os quatro tons saem dessas quatro cores, com contraste garantido. A paleta troca também o fundo: em tema escuro por natureza (`relevo`, `arcade`, `aurora`, `noite`, `terminal`), uma paleta de papel claro (`safira`, `corporativo`, `tinta`…) deixa o tema claro; para manter o visual escuro que o pedido quer, não ponha paleta (ou use uma de papel escuro, como `neon`).
552
+ - **Tema** (`theme`): fontes, raio das bordas, textura e uma **pele** própria que rearruma capa, seção e encerramento, muda o jeito dos slides de conteúdo (título, cartões, marcadores da lista, citação, número grande, frase) e põe ornamentos (`sinal`: faixa zebrada e selo no chapéu; `editorial`: fios e capa centralizada; `noite`: moldura fina; `bauhaus`: círculo, quadrado e triângulo; `terminal`: janela com barra e prompt; `jornal`: fios de jornal e manchete sublinhada; `rabisco`: fitas adesivas e títulos inclinados; `oceano`: ondas e chapéu em pílula; `pop`: adesivos e sombra chapada; `aurora`: brilhos e traço em gradiente; `prata`: limpo e centralizado; `relevo`: ficção científica sóbria (sala de controle de filme, sem néon): grafite profundo, curvas de nível ao fundo, cantoneiras de mira, título leve embaixo à esquerda, rótulos técnicos em monoespaçada; combina com ilustração 3D realista (terreno, cidade, água) e gráfico 3D (`science` com superfície); `arcade`: videogame e fliperama, tela de tubo com linhas de varredura, neon, título em pixel no meio e chão de tijolos de jogo de plataforma; `aluminio`: prata metálico de lançamento de aparelho premium, título cromado embaixo à esquerda e um disco de metal polido; `wine`: o `musgo` em vinho (mesmo arranjo, fontes, faixa e rede na capa): fundo vinho quase preto, vermelho-rosado e rosé, com o vermelho forte só no detalhe; `caderno`: visual thinking em papel claro — título em letra de mão alta (Amatic SC) com traço de lápis, chapéu coral em serifada (Gelasio), frase em lilás, rabiscos de ícones em pastel nos cantos (lupa, ampulheta, engrenagem, lápis, chave, lâmpada); `lousa`: quadro-negro verde com giz — título em giz amarelo (Cabin Sketch) com traço laranja, linha de giz sob o título, poeira e marcas de giz apagado, lâmpada e lápis de giz na capa; `cartaz`: cartaz de protesto em papel cinza com grão — condensada pesada (Bebas Neue) em faixa vermelha torta, chapéu como etiqueta amarela, moldura preta grossa na capa, número da seção num disco amarelo; `infografico`: dados chapados — capa azul com chão verde e nuvem, títulos em maiúsculas, chapéu numa tarja verde, números enormes em condensada; `musgo`: laboratório noturno de bom gosto (verde-musgo quase preto, âmbar e sálvia, serifada Fraunces com o destaque do título em âmbar itálico, rótulos em IBM Plex Mono com fio âmbar, texto em Space Grotesk): grade de pontos que some nas bordas e luz âmbar na capa, seção como separador com o número entre fios na linha do chapéu e o título grande embaixo, e a faixa que corre no pé da capa com os títulos das seções (`ticker`); combina com o terminal de cenas (`motion: {type: console}`) na figura da capa ou num `canvas`; `manual` e `manual-noite`: documentação técnica, sem ornamento, código e texto corrido legíveis — o par claro/escuro do mesmo arranjo, para material de consulta, tutorial e apostila: `manual` imprime bem, `manual-noite` descansa a vista). Nos slides de conteúdo: `sinal` barra de aviso e placas; `editorial` fios finos e citação centralizada; `noite` tudo centralizado e cartões vazados; `bauhaus` faixas de cor primária e círculos; `terminal` título como comando e cartões-janela; `jornal` fios duplos e colunas; `oceano` cartões flutuando e balões; `pop` contorno grosso e sombra dura; `prata` centralizado e sem caixa; `aluminio` cartões de alumínio com chanfro de luz; `relevo` painéis de vidro fosco com traço gelo; `arcade` cartões de 8 bits com borda de pixel e sombra dura; `rabisco` tracejados e números circulados; `aurora` vidro com brilho; `caderno` cartões brancos com moldura grossa pastel (menta, lilás, amarelo, coral) e marcador amarelo contornado; `lousa` cartões contornados a giz com borda torta e marcadores em pingo de giz; `cartaz` cartões brancos girados como fotos coladas, números de lista em etiqueta e destaque em vermelho; `infografico` cartões com a faixa da cor do grupo, números em cartões coloridos e números de lista em círculos coloridos; `musgo`/`wine` cartões vazados que sobem no mouse, números em monoespaçada âmbar, marcador em losango, código em janela com três bolinhas e botões âmbar. Trocar o tema já muda o arranjo: não reescreva slides só para "combinar" com o tema.
553
+ - **Paleta** (`palette`): só as cores, em qualquer tema. `tinta`, `floresta`, `mar`, `entardecer`, `lavanda`, `grafite`, `neon`, `areia`, `cereja`, `corporativo`, `luzquente`, ou as suas: `palette: { paper: "F4F1EA", ink: "161616", accent: "D7263D", alert: "1B998B" }`. Os quatro tons saem dessas quatro cores, com contraste garantido. A paleta troca também o fundo: em tema escuro por natureza (`relevo`, `arcade`, `aurora`, `noite`, `terminal`, `musgo`, `wine`, `lousa`), uma paleta de papel claro (`safira`, `corporativo`, `tinta`…) deixa o tema claro; para manter o visual escuro que o pedido quer, não ponha paleta (ou use uma de papel escuro, como `neon`).
569
554
  - **Paletas de família** (para identidade de marca sem cansar a vista): a cor forte da marca fica só no detalhe (`alert`, a ênfase pontual) e a página trabalha com os parentes mais agradáveis dela (`accent` e `family`). `rubi` (rosas, magenta e vinho; vermelho só no detalhe), `ametista` (roxos e lilases), `tangerina` (laranja com azul-marinho), `safira` (azuis com um toque âmbar), `esmeralda` (verdes). Na sua: `palette: { paper: "FFFFFF", ink: "3B2B33", accent: "B83A6E", alert: "CC092F", family: ["F9DCE5", "EFA3BC", "D9668F", "7E2349"] }` (de 2 a 8 parentes). `family` pinta as séries extras dos gráficos e os grupos e ramos dos diagramas. Pedido de "cores da empresa X": monte uma paleta de família assim, com a cor forte em `alert`. Para clima futurista de bom gosto (luz quente de prédios e shows de drones, nunca neon barato): `luzquente` — brancos quentes e âmbar que funcionam no claro e, no `tone: dark`, viram HUD âmbar sobre carvão quente.
570
555
 
571
556
  - **Identidade** (`identity: trabalho`, no deck): as fontes da empresa da pessoa (e a paleta preferida), configuradas só no computador dela (`~/.sagadeck/identidades.yaml`; no Studio, aba Design, grupo Identidade). Corpo, rótulos e código sempre na fonte da empresa; títulos também, menos nos temas com personalidade (`rabisco`, `pop`, `terminal`, `jornal`, `bauhaus`), que mantêm o título deles. A paleta da identidade vale quando o deck não escolheu outra. Nunca invente o nome de uma identidade: use só a que a pessoa pedir ou a que o deck já tem; numa máquina sem ela, a apresentação sai com as fontes do tema.
@@ -626,25 +611,20 @@ Sagadeck.widget("contador", {
626
611
  ```
627
612
  No YAML: `widgets: [widgets/contador.js]` e `{ widget: contador, rotulo: "Votos" }`. No PowerPoint o widget vira uma imagem do estado final.
628
613
 
629
- ## Texto no cenário (`scenography`)
630
-
631
- Composição estática: o texto permanece editável, integrado a planos, luz e profundidade. `scene`: `stage` (letras monumentais atrás de uma escultura), `floor` (texto no chão), `signs` (placa em perspectiva), `terminal` (terminal hacker), `cafe` (lousa de café com letreiro neon), `travel` (cartão de embarque), `ticker` (pregão com cotações e candles), `marquee` (letreiro de cinema com lâmpadas), `blueprint` (planta técnica), `magazine` (capa de revista), `orbit` (planeta e estrelas), `synthwave` (neon anos 80) ou `gallery` (parede de galeria). Cada uma tem um tamanho de título padrão; `titleSize` vence. Campos: `title` (frase curta, quebra de linha permitida), `kicker`, `subtitle`, `caption`, `titleSize`, `image` (fundo opcional), `imageOpacity` (transparência do fundo, de 0 a 1; padrão 0.85), `foreground` (recorte PNG transparente colocado à frente das letras). Um fundo arbitrário não é segmentado automaticamente: para oclusão de uma pessoa, forneça o recorte em `foreground`.
632
-
633
- Demonstração com todas: biblioteca, Nova, "Exemplo: texto no cenário".
634
-
635
- ```yaml
636
- - layout: scenography
637
- scene: floor
638
- title: "NOVOS\nCAMINHOS"
639
- kicker: APRENDER PARA TRANSFORMAR
640
- caption: WORKSHOP / BRIDGE
641
- deco: none
642
- ```
643
-
644
614
  ## Projeto: a pasta da apresentação
645
615
 
646
616
  No Studio, a pasta do deck é um projeto (aba **Arquivos**, à esquerda): o `.yaml`, `imagens/`, `contexto/` (anexos, prints colados, planilhas, anotações `.md`) e `.sagadeck/` (a conversa do chat, o cache e a lixeira do projeto, do próprio Studio). O texto do que está em `contexto/` chega a você junto do pedido, como material anexado (com o caminho, ex.: `contexto/vendas.csv`): use os números e fatos de lá. Uma planilha de `contexto/` pode alimentar um gráfico com `csv: contexto/vendas.csv` (CSV) ou pela sugestão de gráficos da planilha no Studio (que grava `from:`).
647
617
 
618
+ ## Exportação pelo Studio
619
+
620
+ Arquivo › Baixar PowerPoint, PDF, roteiro, material de estudo ou Baixar tudo inicia a geração **no servidor do
621
+ Studio** (na própria máquina no modo local). O painel **Exportações** mostra a etapa, o slide atual, o tempo
622
+ decorrido e **Pronto para baixar**, ou a falha. Ele também acompanha os downloads pelo menu do cartão da biblioteca.
623
+ A geração continua ao fechar/recarregar a aba; ao voltar ao editor ou à biblioteca, o arquivo pode ser baixado
624
+ pela mesma lista. Guarda as dez exportações mais recentes da pessoa, por até 24 h enquanto o Studio estiver ligado.
625
+ Exportar a demo em prévia não cria uma cópia pessoal. Não há aviso por email. Ao orientar a pessoa a obter o PPTX,
626
+ indique o menu e o painel; só afirme que o arquivo foi gerado quando houver resultado real de exportação.
627
+
648
628
  ## Apresentação importada de PowerPoint
649
629
 
650
630
  Um `.pptx` importado (Biblioteca › Importar apresentação, ou `sagadeck importar arquivo.pptx`) chega **fiel ao original**: cada slide é um `canvas` com os elementos na mesma posição, e o deck tem `import: { from, slides, fonts, snapshots }` e `footer: false` (o original tem o próprio rodapé). Cada slide traz `original: { slide: 7, image: original/slide-07.png }` (a foto do slide original, quando o PowerPoint ou o LibreOffice estavam disponíveis) e a pasta `original/` guarda a cópia do arquivo. Elementos que só aparecem em slides importados:
@@ -696,28 +676,36 @@ escola, cinema…) e qualquer traçado ou área (rede, trajeto, bairro, área de
696
676
  legend: mil m³
697
677
  ```
698
678
 
679
+ - `geojson:` também aceita o GeoJSON escrito no próprio slide (FeatureCollection, Feature ou só a geometria), para um
680
+ desenho pequeno; dados de verdade ficam num arquivo do projeto. Nunca invente o traçado de algo real.
699
681
  - `points:` também aceita a lista no próprio slide: `[{ nome: Centro, lat: -23.55, lon: -46.63, status: ativo }]`.
700
682
  Uma coluna só com "lat, lon" vale (`coordenadas`, `posicao`). Use ponto ou vírgula decimal; nunca invente
701
683
  coordenadas: elas vêm da planilha, do arquivo ou de uma busca. Linha sem posição válida fica de fora (o fiscal avisa).
702
684
  - `color:` aceita também uma cor fixa (`s1`, `em`, `hi`, `alert`, `#1F6FB2`). `step` (número) diz em que clique a
703
685
  camada aparece; `view` da camada (`fit` ou `{ center: [lat, lon], zoom }`) leva a câmera até ela nesse clique.
704
686
  - `view:` do slide fixa o enquadramento (`{ center: [-23.55, -46.63], zoom: 13 }`); sem ele, o mapa enquadra os dados.
687
+ - `basemap: claro` e `escuro` usam fundos vetoriais do OpenFreeMap, sem chave: o mar tem cor própria e a fronteira
688
+ marítima não aparece, preservando o litoral e as divisas terrestres. `ruas` continua no OpenStreetMap. Em
689
+ **Configurar mapa**, os fundos claro e escuro podem usar outro estilo vetorial (JSON) ou tiles com `{z}/{x}/{y}`.
705
690
  - Planilha só com endereço (sem latitude e longitude): no Studio, a planilha aberta (aba Arquivos) tem **Achar
706
691
  coordenadas**, que pergunta antes de mandar os endereços para o serviço de fora e grava as colunas `latitude` e
707
692
  `longitude`; **Pôr no mapa** cria o slide a partir dela. Sugira esses botões em vez de inventar coordenadas.
708
693
  Com um slide de mapa selecionado, a planilha fica ao lado dele: clicar num ponto seleciona a linha e selecionar
709
694
  uma linha abre o cartão do ponto. O enquadramento automático deixa os pontos livres da legenda.
710
- - **Editar no mapa** (botão na prévia do slide, no Studio): a pessoa clica para criar pontos (vão para a planilha da
711
- camada, com o endereço preenchido), desenha linhas e áreas (vão para o GeoJSON da camada; "Seguir as ruas" liga os
712
- cliques pelo serviço de rotas), arrasta pontos e vértices, divide e junta linhas, mede com a régua e grava o
713
- enquadramento ("Usar esta vista"). Quando a pessoa quiser marcar algo à mão no mapa, indique esse botão.
695
+ - **Editar mapa** (botão na prévia do slide, ou dois cliques no mapa, no Studio): abre uma tela só do mapa. À esquerda
696
+ as camadas; no meio o mapa grande com Selecionar, Ponto, Linha, Área e Régua; à direita as propriedades do que está
697
+ selecionado (os campos de um ponto, linha, área ou região, com o que cada um faz no mapa) ou, sem seleção, da camada
698
+ (cor, tamanho, rótulo, cartão, quando aparece) e do mapa (fundo, enquadramento). Pontos novos vão para a planilha da
699
+ camada, com o endereço preenchido, ou para a lista do slide; linhas e áreas para o GeoJSON da camada ou para o slide
700
+ ("Seguir as ruas" liga os cliques pelo serviço de rotas). Arrasta pontos e vértices, divide e junta linhas e grava o
701
+ enquadramento ("Usar a vista de agora"). Quando a pessoa quiser marcar ou corrigir algo à mão no mapa, indique esse botão.
714
702
  - **Dados de fora** (lugares de um tipo, linhas como ciclovias, o contorno de um lugar com nome, uma lista da web,
715
703
  coordenadas da planilha da pessoa): peça com o bloco `mapa:` (as regras vêm no prompt); o Studio busca, grava os
716
704
  arquivos em `contexto/` com a fonte de cada linha e te devolve o que gravou. Nunca invente coordenada nem contorno.
717
705
  - **Análises** (o mais próximo e a distância, quantos num raio ou numa área, faixa em volta de uma linha, onde
718
706
  instalar o próximo, rota com tempo, área alcançável em X minutos, rastro de GPS encaixado nas ruas): também pelo
719
707
  bloco `mapa:`; o Studio calcula e devolve os números. Nunca calcule distância, contagem ou tempo de cabeça.
720
- - Serviços (Configurar mapa, opcional): sem chave, tudo funciona com os serviços públicos do OpenStreetMap; a chave
708
+ - Serviços (Configurar mapa, opcional): sem chave, os fundos usam OpenStreetMap/OpenFreeMap e os dados vêm dos serviços públicos do OpenStreetMap; a chave
721
709
  gratuita do OpenRouteService só acrescenta rotas a pé/de carro/de bicicleta confiáveis e área alcançável.
722
710
  - Ao apresentar: clicar num ponto, linha ou área abre o cartão com os dados; clicar na legenda liga e desliga uma
723
711
  categoria ou a camada inteira. O fundo vem da internet; sem rede, aparece um aviso e as camadas continuam. No PDF e
@@ -875,9 +863,9 @@ Os três aceitam `kicker`, `title` e `items: [{title, text, value, icon, code, f
875
863
  - `ribbon`: os mesmos campos em cápsulas arredondadas, centralizadas. Para serviços, etapas ou pilares.
876
864
  - `dossier`: página de consulta, compacta: letra menor e blocos de código (`code`) com quebra de linha. Para material de referência (documentação, payloads, instruções); não imponha a ela o limite de palavras de uma palestra quando a pessoa pede material denso.
877
865
 
878
- No Studio, todo tipo de slide (página de consulta, grade adaptável, diagrama, tipografia cinética, status semanal…) sai da galeria **Novo slide** (Início › Escolher tipo ou Inserir › Novo slide), com busca e categorias; **Layout** troca o formato do slide atual e leva o conteúdo junto. A aba **Avançado** muda a densidade do slide atual: **Padrão**, **Compacta** ou **Mais conteúdo**. A densidade reduz espaçamentos e tamanhos sem apagar o conteúdo; para explicações longas com seções, prefira `dossier`.
866
+ No Studio, todo tipo de slide (página de consulta, grade adaptável, diagrama, status semanal…) sai da galeria **Novo slide** (Início › Escolher tipo ou Inserir › Novo slide), com busca e categorias; **Layout** troca o formato do slide atual e leva o conteúdo junto. A aba **Avançado** muda a densidade do slide atual: **Padrão**, **Compacta** ou **Mais conteúdo**. A densidade reduz espaçamentos e tamanhos sem apagar o conteúdo; para explicações longas com seções, prefira `dossier`.
879
867
 
880
- Para apresentações completas de exemplo, abra **Abrir demos completos** na aba Avançado (ou **Nova → Modelo pronto → Recursos avançados** na biblioteca). Esse demo reúne código denso, página de consulta, grade com oito itens, aviso de segurança, diagrama e tipografia cinética.
868
+ Para apresentações completas de exemplo, abra **Abrir demos completos** na aba Avançado (ou **Demos oficiais** na biblioteca): uma demo por assunto — mapas, programação (código denso, página de consulta, Git a dois, diagramas), APIs com curl, aula de hidráulica, aula de algoritmos e diagramas vivos.
881
869
 
882
870
  Modelos, estilos, demos e exemplos de **Modelo pronto** (na vitrine, "Visuais para começar" e "Recursos do SagaDeck", com a capa de cada um) abrem em **prévia**: dá para navegar, apresentar e experimentar sem criar arquivo. A primeira mudança (ou o botão **Usar como base**) cria uma cópia na biblioteca, no tópico de onde veio (padrão `Modelos`), com as imagens; o modelo de fábrica nunca muda.
883
871
 
@@ -901,13 +889,13 @@ As formas clássicas de slide de consultoria, desenhadas na hora para a quantida
901
889
  ```yaml
902
890
  - layout: infographic
903
891
  shape: metro
904
- title: Os caminhos de um projeto na Bridge
905
- center: { title: Bridge, text: Um pedido, vários caminhos }
892
+ title: Os canais de uma loja
893
+ center: { title: Loja, text: Um pedido, vários caminhos }
906
894
  items:
907
- - { title: Lote, text: Databricks chama a Bridge de madrugada, icon: moon }
908
- - { title: Teams, text: Copilot Studio + Power Automate, icon: message-square }
909
- - { title: App próprio, text: Wave, arquitetura, infra e rede, icon: app-window }
910
- - { title: SaaS externo, text: Túnel mTLS e serviço extra, icon: globe }
895
+ - { title: Balcão, text: Atendimento na hora, icon: store }
896
+ - { title: App, text: Pede e retira na loja, icon: smartphone }
897
+ - { title: Site, text: Entrega em casa, icon: truck }
898
+ - { title: Parceiros, text: Vitrine em outros sites, icon: globe }
911
899
  ```
912
900
 
913
901
  Infográfico × diagrama: infográfico é para itens paralelos em volta de uma ideia (sem fluxo entre eles, ou com o fluxo simples de `trilhas`) e para **ciclos** (`ciclo`: num fluxograma, a volta ao começo vira setas longas cruzando o desenho); `diagram` (Mermaid) é para processo com decisões, sequência entre sistemas, arquitetura e UML.
@@ -918,7 +906,7 @@ Para processo, fluxo, arquitetura, UML, sequência entre sistemas, ciclo de vida
918
906
 
919
907
  Direção automática: em fluxogramas o sagadeck desenha deitado (`LR`) e em pé (`TB`) e usa o que deixa a letra maior na área do slide. Escreva a direção que fizer sentido; `autoDirection: false` no slide mantém a do código (use só se a pessoa pedir uma direção).
920
908
 
921
- Tipos (primeira linha do código): `flowchart LR` / `flowchart TB` (fluxo, processo, arquitetura), `sequenceDiagram` (quem chama quem, pedido e resposta), `stateDiagram-v2` (ciclo de vida: DEV → HOM → PROD), `classDiagram` e `erDiagram` (UML e modelo de dados), `journey` (jornada com notas), `mindmap` (mapa de ideias, sopa de letrinhas organizada), `timeline`, `block-beta` (blocos de arquitetura), `gantt`, `quadrantChart`, `gitGraph` (branches e commits do Git: `commit`, `branch nome`, `checkout nome`, `merge nome`, `cherry-pick id: "…"`; é o diagrama certo para "linhas de commits", rebase × merge e fluxo de branches).
909
+ Tipos (primeira linha do código): `flowchart LR` / `flowchart TB` (fluxo, processo, arquitetura), `sequenceDiagram` (quem chama quem, pedido e resposta), `stateDiagram-v2` (ciclo de vida: rascunho → revisão → publicado), `classDiagram` e `erDiagram` (UML e modelo de dados), `journey` (jornada com notas), `mindmap` (mapa de ideias, sopa de letrinhas organizada), `timeline`, `block-beta` (blocos de arquitetura), `gantt`, `quadrantChart`, `gitGraph` (branches e commits do Git: `commit`, `branch nome`, `checkout nome`, `merge nome`, `cherry-pick id: "…"`; é o diagrama certo para "linhas de commits", rebase × merge e fluxo de branches).
922
910
 
923
911
  ```yaml
924
912
  - layout: diagram
@@ -943,26 +931,26 @@ Setas no `flowchart`: `-->` normal, `-.->` pontilhada (opcional, eventual), `==>
943
931
 
944
932
  ```yaml
945
933
  - layout: diagram
946
- kicker: Governança
947
- title: Do pedido de acesso à ==produção==
948
- caption: Experimento é prorrogável; em HOM e PROD as chaves ficam no Key Vault
934
+ kicker: Processo
935
+ title: Do pedido à ==entrega==
936
+ caption: Sob medida leva mais tempo; o fornecedor entrega o material da montagem
949
937
  mermaid: |
950
938
  flowchart LR
951
- A([:key-round: Pedido de acesso]):::hi --> B{Experimento ou projeto?}
952
- subgraph EXP[Experimento]
953
- C[:flask-conical: 30 dias, dados fictícios]
939
+ A([:shopping-cart: Pedido]):::hi --> B{Tem em estoque?}
940
+ subgraph EST[Estoque]
941
+ C[:package: Separar e embalar]
954
942
  end
955
- subgraph PRJ[Projeto]
956
- D[DEV 30 dias] ==> E[HOM 30 dias] ==> F[:rocket: PROD]:::em
943
+ subgraph PRD[Sob medida]
944
+ D[Cortar] ==> E[Montar] ==> F[:truck: Enviar]:::em
957
945
  end
958
- B -->|experimento| C
959
- B -->|projeto| D
960
- C -.->|deu certo| D
961
- K[(Key Vault via RITM)]:::suave -.- E
946
+ B -->|sim| C
947
+ B -->|não| D
948
+ C -.->|pronto| F
949
+ K[(Fornecedor)]:::suave -.- E
962
950
  ```
963
951
 
964
952
  Regras de bom desenho (siga sempre):
965
- - Agrupe com `subgraph` o que é da mesma área, time, camada ou fase (Front-end, Bridge, Segurança; DEV, HOM, PROD): é o que dá cor e organização ao desenho. 2 a 5 grupos por slide.
953
+ - Agrupe com `subgraph` o que é da mesma área, time, camada ou fase (Front-end, Back-end, Segurança; rascunho, revisão, publicado): é o que dá cor e organização ao desenho. 2 a 5 grupos por slide.
966
954
  - Coisas de fora (usuário, sistema externo, banco de terceiros) com `:::suave`, fora dos grupos.
967
955
  - Rótulos curtos: 1 a 4 palavras por nó (detalhe vai em `caption`, nas `notes` ou em outro slide). Rótulo de seta com 1 a 3 palavras.
968
956
  - No máximo ~12 nós por slide. Processo maior: divida em slides (visão geral primeiro, depois um slide por fase) em vez de encolher tudo.
@@ -992,6 +980,8 @@ ficam na pasta `imagens/` da apresentação.
992
980
 
993
981
  ## Ajustes diretos no Studio
994
982
 
983
+ No editor, **Assistente** fica por último à direita no cabeçalho do painel, separado de Formatar, Propriedades e Variáveis. Seu nome permanece visível ao usar qualquer opção. O editor abre no Assistente, respeitando quem fechou o painel; nesse caso, o atalho flutuante reabre o chat. Trocar de opção mantém a conversa e o rascunho.
984
+
995
985
  Em **Inserir → Neste slide**: Texto, Formas (menu com 12 desenhos: retângulo, arredondado, elipse, pílula, linha, triângulo, losango, hexágono, estrela, seta, chevron, balão), Imagem e Ícone adicionam elementos sem trocar o layout. Um clique em qualquer ponto de um objeto (texto, forma, imagem) o seleciona; clicar de novo no texto selecionado (ou duplo clique) escreve. Arrastar numa área vazia desenha um retângulo que seleciona vários; Shift+clique soma. Selecionados, dá para arrastar juntos, mover com as setas, redimensionar pela alça (um só) e usar a barra que flutua acima da seleção: tamanho e cor do texto, preenchimento da forma (`visualEdits.fill`), trazer para frente, enviar para trás (fica atrás dos outros objetos, nunca do fundo), excluir, alinhar (esquerda, centro, direita, em cima, meio, embaixo: vários entre si; um só, no slide), distribuir (3 ou mais, mesmo espaço), copiar e colar estilo (Ctrl+Alt+C / Ctrl+Alt+V), travar (o clique atravessa) e, numa imagem, trocar a imagem (`visualEdits.image`, com `fit: cover|contain` e `focus`: center, top, bottom, left, right, top left…). Ao arrastar, guias grudam nas bordas e no centro do slide e dos outros objetos (Alt solta). Na aba Propriedades, **Objetos do slide** lista tudo o que está no slide: seleciona até o travado, oculta/mostra e trava/destrava (`locked`; a decoração que veio do PowerPoint, `deco: true`, já vem travada). Tab/Shift+Tab passam de um objeto para outro; Escape solta. A aba **Propriedades** do painel lateral é o inspetor (como o Object Inspector): mostra só as categorias que fazem sentido para o que está selecionado (Posição e tamanho; Texto; Preenchimento e contorno; Aparência; Animação; Avançado) e, sempre, as do Slide e da Apresentação. Os ajustes de objeto ficam em `visualEdits` (`dx, dy, w, h, rotate, z, size, color, weight, italic, align, lineHeight, letterSpacing, uppercase, fill, stroke, strokeWidth, radius, opacity, shadow: suave|forte, step, anim, hidden, locked, image, fit, focus`); não os invente ao criar um deck. Delete/Backspace excluem o objeto selecionado (fica em `visualEdits` como `hidden`, recuperável); Ctrl+Z / Ctrl+Y desfazem e refazem qualquer mudança da apresentação (a da tela, a do formulário, a do assistente), com os botões ao lado do título. Duplo clique permite voltar a escrever. Os ajustes são persistidos em `visualEdits`, com chaves geradas pelo renderizador; não invente essas chaves ao criar um deck. Prefira alterar os campos semânticos. A exclusão visual usa `hidden` para preservar conteúdo recuperável. Mudanças estruturais grandes podem invalidar ajustes: remova `visualEdits` ao reconstruir um slide.
996
986
 
997
987
  `Arrumar layout` (aba Revisar) é local e baseado em regras: corrige sobreposição, margem, título comprido e texto que não coube, diz o que fez e se desfaz. `Revisar com IA` envia a imagem renderizada do slide ao modelo configurado e solicita melhorias; usa tokens. O status de IA abre Configurar IA (provedor, chave e modelos desta máquina). Um modelo sem visão é identificado na resposta; conectividade com `/models` não comprova que uma geração será aceita pelo provedor.
@@ -1124,6 +1114,20 @@ elements:
1124
1114
 
1125
1115
  Integre o movimento à direção de arte: geometria ligada a uma figura, pulsos numa linha de processo, detalhe que acompanha uma moldura ou tipografia, cores e escala da mesma composição. Não traduza “eco animado” em retângulos opacos soltos e repetidos no canto. Uma identidade tecnológica deve existir também nas cores, formas e hierarquia do slide; um widget não resolve uma página genérica. Use elementos `motion` posicionados em `add`/`canvas` quando uma integração específica pedir outro lugar/tamanho, mantendo conteúdo e controles livres. Estas são escolhas pelo briefing e assunto, não uma receita obrigatória para toda apresentação.
1126
1116
 
1117
+ `type: console` é a janela de terminal em cenas: barra com três bolinhas, legenda (`caption`) e contador (01/03); em cada cena o comando (`cmd`) é digitado letra a letra depois do prompt, e a saída (`out`, lista de linhas; a primeira em destaque, como o status de uma resposta) aparece linha a linha; segura a leitura (`hold`, segundos, padrão 3.2) e passa para a próxima cena, em ciclo. Bom para mostrar chamadas de API (`curl`) e suas respostas, ou comandos e resultados. Parado (movimento reduzido, `motion: none`, exportação), mostra a primeira cena completa. Aceita `typing` (segundos por letra, padrão 0.016), `speed`, `fontSize` (padrão 20) e as cores de sempre (fundo, texto, `accent` no prompt e no cursor, `secondary` na primeira linha da saída). É ilustração, não execução: para chamar a API de verdade, use o slide `api`.
1118
+
1119
+ ```yaml
1120
+ figure:
1121
+ motion:
1122
+ type: console
1123
+ caption: contrato do agente — ao vivo
1124
+ scenes:
1125
+ - cmd: "curl -X POST /api/memorias -d '{\"texto\":\"usar pnpm\"}'"
1126
+ out: ["201 Created", "{ \"id\": \"9f3a\" }"]
1127
+ - cmd: "curl '/api/memorias?q=pnpm'"
1128
+ out: ["200 OK · 4 ms", "{ \"total\": 0.74 }"]
1129
+ ```
1130
+
1127
1131
  `type: terminal` digita lentamente um roteiro fornecido em `lines: [linha, linha]` ou `code: texto`, com cursor e rolagem, sem executar o código. Aceita `typing` (segundos por caractere), `speed` e `fontSize` (10–40). Repete após uma pausa de leitura e pausa fora do slide. Para um painel legível de código ao lado de logs rápidos, combine terminal com requests, reservando área suficiente para ambos. O roteiro é do conteúdo solicitado, nunca uma API real inventada sem identificação de exemplo.
1128
1132
 
1129
1133
  ### Abertura com chat preciso e filme separado
@@ -1169,6 +1173,23 @@ No chat, `run.language: web` recebe `code` como JSON: `{"action":"search","query
1169
1173
 
1170
1174
  ## Diagnósticos e suporte
1171
1175
 
1176
+ **O que de IA funciona nesta máquina:** `sagadeck ia-check` (também `POST /api/ia/check` no Studio local e a ferramenta
1177
+ `sagadeck_ia_check` do MCP). Cada recurso com uma chamada de verdade ao provedor configurado, todos ao mesmo tempo, e
1178
+ cada resultado sai assim que chega:
1179
+ - **texto**: pergunta curta com resposta conhecida;
1180
+ - **visão**: uma imagem com duas faixas de cor sorteadas; o modelo precisa dizer as cores na ordem (modelo que não
1181
+ aceita imagem falha, em vez de responder sem ver);
1182
+ - **imagem**: gera uma imagem pequena e confere que voltou PNG, JPEG, WebP ou GIF (grava o arquivo e diz onde);
1183
+ - **pesquisa**: o modelo de pesquisa precisa dizer a data de hoje;
1184
+ - **vídeo**: sem `--video-real`, só confere o modelo no catálogo, de graça, e sai `SEM PROVA`; com `--video-real`,
1185
+ gera o clipe mais curto e leve que o modelo aceita, acompanha, baixa e confere o MP4 (cobrado; leva minutos).
1186
+
1187
+ `--rapido` pula imagem e vídeo; `--so=texto,visao` escolhe; `--json` para máquina (o andamento vai para o stderr); sai
1188
+ com código 1 se algo falhou. O vídeo usa a mesma camada da IA quando há um **modelo de vídeo** em Configurar IA
1189
+ (endereço, chave e adaptador de lá); sem ele, o OpenRouter com `SAGADECK_VIDEO_KEY` ou `OPENROUTER_API_KEY`.
1190
+ `SAGADECK_VIDEO_URL` e `SAGADECK_VIDEO_MODEL` trocam endereço e modelo. Sem catálogo no provedor, o vídeo é gerado
1191
+ assim mesmo (o catálogo só valida quando existe).
1192
+
1172
1193
  Falhas do Studio e da IA devem explicar a operação, distinguir causa comprovada de causa desconhecida e informar código + referência para suporte. Motivos informados pelo provedor são preservados, inclusive em streaming: limite de tokens não é timeout. Nunca atribua uma falha a tokens sem finish_reason: length. Visão de documentos usa SAGADECK_DOCUMENT_VISION_TOKENS (padrão 5000 por página, entre 256 e 32000); quando o provedor informa limite, tenta uma vez com o dobro, até 32000. SAGADECK_LLM_TIMEOUT controla espera sem resposta (padrão 180 s); SAGADECK_LLM_FIRST_TIMEOUT controla primeira resposta em streaming (padrão 600 s). Nenhuma resposta parcial é apresentada como extração completa. Cancelamento é uma ação normal, sem aviso de erro de suporte.
1173
1194
 
1174
1195
  ### Prioridade das figuras e Word legado
package/package.json CHANGED
@@ -1,15 +1,32 @@
1
1
  {
2
2
  "name": "sagadeck",
3
- "version": "1.8.0",
3
+ "version": "1.9.0",
4
4
  "description": "Gerador de apresentações: YAML -> HTML animado + PowerPoint editável, com temas e figuras geradas na hora.",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "sagadeck": "bin/sagadeck.js"
8
8
  },
9
9
  "engines": {
10
- "node": ">=18"
10
+ "node": ">=22.13.0"
11
11
  },
12
12
  "license": "MIT",
13
+ "homepage": "https://github.com/naruminho/sagadeck#readme",
14
+ "bugs": {
15
+ "url": "https://github.com/naruminho/sagadeck/issues"
16
+ },
17
+ "keywords": [
18
+ "apresentacoes",
19
+ "slides",
20
+ "presentation",
21
+ "pptx",
22
+ "powerpoint",
23
+ "pdf",
24
+ "yaml",
25
+ "llm",
26
+ "ai",
27
+ "generator",
28
+ "cli"
29
+ ],
13
30
  "dependencies": {
14
31
  "jszip": "^3.10.2",
15
32
  "katex": "^0.18.9",
@@ -21,19 +38,33 @@
21
38
  "qrcode-generator": "^2.0.4",
22
39
  "yaml": "^2.9.1"
23
40
  },
41
+ "overrides": {
42
+ "image-size": "^2.0.4"
43
+ },
24
44
  "devDependencies": {
25
45
  "@fontsource-variable/caveat": "^5.3.0",
46
+ "@fontsource-variable/fraunces": "^5.3.0",
26
47
  "@fontsource-variable/fredoka": "^5.3.0",
48
+ "@fontsource-variable/gelasio": "^5.3.0",
27
49
  "@fontsource-variable/inter": "^5.3.0",
50
+ "@fontsource-variable/montserrat": "^5.3.0",
28
51
  "@fontsource-variable/plus-jakarta-sans": "^5.3.0",
52
+ "@fontsource-variable/space-grotesk": "^5.3.0",
53
+ "@fontsource/amatic-sc": "^5.3.0",
54
+ "@fontsource/bebas-neue": "^5.3.0",
55
+ "@fontsource/cabin-sketch": "^5.3.0",
29
56
  "@fontsource/comic-neue": "^5.3.0",
57
+ "@fontsource/ibm-plex-mono": "^5.3.0",
58
+ "@fontsource/itim": "^5.3.0",
30
59
  "@fontsource/patrick-hand": "^5.3.0",
31
60
  "@fontsource/press-start-2p": "^5.3.0",
32
61
  "@fontsource/vt323": "^5.3.0",
62
+ "@maplibre/maplibre-gl-leaflet": "0.1.4",
33
63
  "@material-symbols/svg-400": "^0.47.5",
34
64
  "esbuild": "^0.28.2",
35
65
  "jsqr": "^1.4.0",
36
66
  "leaflet": "1.9.4",
67
+ "maplibre-gl": "6.13.0",
37
68
  "mermaid": "^11.17.2"
38
69
  },
39
70
  "scripts": {
@@ -11,7 +11,7 @@ import { spawn } from "node:child_process";
11
11
  import fs from "node:fs";
12
12
  import path from "node:path";
13
13
  import os from "node:os";
14
- import { videoOperation } from './video-generation.js';
14
+ import { videoOperation, videoSetup } from './video-generation.js';
15
15
  import { webOperation } from './web-operation.js';
16
16
 
17
17
  // Registro de auditoria: cada comando pedido pela IA (aprovado, recusado ou executado), uma linha JSON em
@@ -69,7 +69,7 @@ export async function runCommand(request, { cwd, env = {}, mask = (s) => s, time
69
69
  }
70
70
  if(language==='video'){
71
71
  let args; try { args = typeof code === 'object' && code !== null ? code : JSON.parse(code); } catch(e) { return {language,exitCode:1,stdout:'',stderr:mask(`run.code precisa de JSON válido: ${e.message}`),timedOut:false}; }
72
- try{return{language,exitCode:0,stdout:mask(JSON.stringify(await videoOperation(args,{cwd,key:env.SAGADECK_VIDEO_KEY||env.OPENROUTER_API_KEY||process.env.SAGADECK_VIDEO_KEY||process.env.OPENROUTER_API_KEY}))),stderr:'',timedOut:false};}
72
+ try{return{language,exitCode:0,stdout:mask(JSON.stringify(await videoOperation(args,{cwd,setup:videoSetup({env:{...process.env,...env}})}))),stderr:'',timedOut:false};}
73
73
  catch(e){return{language,exitCode:1,stdout:'',stderr:mask(e.message),timedOut:false};}
74
74
  }
75
75
  const win = process.platform === "win32";
package/src/ai/deck-ai.js CHANGED
@@ -69,7 +69,7 @@ Siga ESTRITAMENTE a referência abaixo: use só layouts, elementos, campos e fig
69
69
  - ANTI-FEIJÃO-COM-ARROZ: varie os layouts de verdade; capa (cover) no início e encerramento (end) no fim quando fizer sentido. Regras duras: nunca 2 slides seguidos com o mesmo layout (salvo série intencional); em 6+ slides use 5+ layouts diferentes com 1 slide de impacto (headline, number, statement, full, image, question); no máximo 45% do deck em listas/cartões (cards, list, steps, stats, bento, agenda). Conteúdo manda no layout, não o contrário (ver o mapa em "Layouts válidos").
70
70
  - Slide denso (documentação, referência, números): feche com 1 takeaway em ==destaque== e use o elemento \`aviso\` (tipos: \`importante\`, \`atencao\`, \`dica\`, \`perigo\`) para o que não pode passar batido; grife ==palavras-chave== no texto corrido em vez de encher de negrito.
71
71
  - Escreva no idioma do pedido do usuário.
72
- - Layouts válidos (\`layout:\`): ${Object.keys(LAYOUTS).join(", ")}. Conteúdo → layout (use o que comunica, não o mais fácil): processo/fluxo/arquitetura/UML: layout \`diagram\` (Mermaid); itens em volta de uma ideia: layout \`infographic\`; gráfico: \`chart\` (fórmula/curva/3D: \`science\`); datas: \`calendar\` (grade) ou \`timeline\` (marcos); página densa estilo revista: \`poster\`; jornada+problema+solução+painel: \`onepage\`; status semanal: \`status\`; definição: \`definition\`; citação: \`quote\`; número gigante: \`number\`; KPIs: \`stats\`; A×B: \`compare\`; 2×2: \`matrix\`; pergunta à plateia: \`question\`/\`poll\`; código: \`code\`, guiado: \`codewalk\`; screenshot com foco: \`spotlight\`; API ao vivo: \`api\`; conta/calculadora: \`solution\`/\`calc\`; algoritmo animado: \`algo\`; redes/rotas: \`graphlab\`; código executável pelo aluno: \`codelab\`; experimento: \`playground\`; decisão: \`decisionlab\`; duelo/terminais/turnos: \`duel\`/\`terminals\`/\`turns\`; carrossel: \`carousel\`; funil/pirâmide/agenda: \`funnel\`/\`pyramid\`/\`agenda\`; grade/consulta: \`bento\`/\`mosaic\`/\`ribbon\`/\`dossier\`; tipografia em cena: \`kinetic\`; texto no cenário: \`scenography\`; caminhos com volta ao mapa: \`hub\`+\`goto\`/\`back\`/\`next\`; manchete: \`headline\`; imagem total: \`full\`/\`image\`. Diagramas simples (\`diagram: loop/flow/venn…\`) e gráficos também existem como ELEMENTOS, dentro de figure/content/side.
72
+ - Layouts válidos (\`layout:\`): ${Object.keys(LAYOUTS).join(", ")}. Conteúdo → layout (use o que comunica, não o mais fácil): processo/fluxo/arquitetura/UML: layout \`diagram\` (Mermaid); itens em volta de uma ideia: layout \`infographic\`; gráfico: \`chart\` (fórmula/curva/3D: \`science\`); datas: \`calendar\` (grade) ou \`timeline\` (marcos); página densa estilo revista: \`poster\`; jornada+problema+solução+painel: \`onepage\`; status semanal: \`status\`; definição: \`definition\`; citação: \`quote\`; número gigante: \`number\`; KPIs: \`stats\`; A×B: \`compare\`; 2×2: \`matrix\`; pergunta à plateia: \`question\`/\`poll\`; código: \`code\`, guiado: \`codewalk\`; screenshot com foco: \`spotlight\`; API ao vivo: \`api\`; conta/calculadora: \`solution\`/\`calc\`; algoritmo animado: \`algo\`; redes/rotas: \`graphlab\`; código executável pelo aluno: \`codelab\`; experimento: \`playground\`; decisão: \`decisionlab\`; duelo/terminais/turnos: \`duel\`/\`terminals\`/\`turns\`; carrossel: \`carousel\`; funil/pirâmide/agenda: \`funnel\`/\`pyramid\`/\`agenda\`; grade/consulta: \`bento\`/\`mosaic\`/\`ribbon\`/\`dossier\`; caminhos com volta ao mapa: \`hub\`+\`goto\`/\`back\`/\`next\`; manchete: \`headline\`; imagem total: \`full\`/\`image\`. Diagramas simples (\`diagram: loop/flow/venn…\`) e gráficos também existem como ELEMENTOS, dentro de figure/content/side.
73
73
  - Temas disponíveis: ${themes}.
74
74
  - YAML: coloque entre aspas duplas todo texto que comece com marcação (\`**\`, \`*\`, \`==\`, \`^^\`, \`~~\`, \`[\`) ou que contenha ": ".
75
75
  - Em sequências inline ([{...}]): coloque entre aspas todo valor de texto com vírgula ("3,5 peixes por m³"). Sem aspas a vírgula parte o objeto e o dado sai truncado.