Ir ao conteúdo
SEED engenhariaDesign System

Boas práticas

7. Apresentações — biblioteca de componentes de slide

seed-praticas.md v0.1 · §07seção 9 de 1707-apresentacoes-biblioteca-de-componentes-de.md · MD5 2630813f

Título completo no canon: Apresentações — biblioteca de componentes de slide (maio/2026)

Origem: seed-ds-slide/references/componentes-slide-seed.md (skill de 2026-05-13, 18615 bytes, MD5 a40d0b6bb931f85dfdad1259a7bffcf9; cópia preservada em 09-pesquisa/skills-v1-2026-05/referencias/componentes-slide-seed.md) · Importado em 2026-09-06 sem edição — só os títulos foram rebaixados dois níveis (código intacto).

Estado: ⚠ não auditado contra o DS v2. Contradições medidas — vale a regra de precedência do cabeçalho: 15 cor(es) em hex — só os tokens do seed-tokens.json valem (marca §3, §11) · cita a Indie Flower — fonte APOSENTADA em 2026-07-30 (marca §4.4); a celebratória é a Caveat (§4.3).

Componentes de slide SEED — biblioteca canônica#

Reference exclusiva da skill seed-ds-slide. Define os 10 layouts de slide aplicáveis em decks PPTX SEED, com regras visuais, dimensões explícitas e código python-pptx típico.

REGRA DURA: todo elemento posicionável em python-pptx (add_textbox, add_picture, add_shape) requer 4 valores explícitos — left, top, width, height em Inches. Sem isso, python-pptx empilha os elementos a partir do canto superior esquerdo e gera overlay/overflow. Issue identificado em produção: stat callout com 3 números sem coordenadas explícitas → números de 72pt sobrepondo os labels. Sempre declarar geometria.

Configuração base do Slide Master#

from pptx import Presentation
from pptx.util import Inches, Pt, Emu
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_ALIGN
from pptx.enum.shapes import MSO_SHAPE

prs = Presentation()
prs.slide_width = Inches(10)       # 16:9 widescreen
prs.slide_height = Inches(5.625)

# Paleta SEED canônica — 18 tokens (de paleta.md)
# Primárias
SEED_TURQUESA          = RGBColor(0x11, 0xB0, 0xA0)  # #11B0A0
BRANCO                 = RGBColor(0xFF, 0xFF, 0xFF)  # #FFFFFF

# Secundárias
SEED_AMARELO           = RGBColor(0xFA, 0xD6, 0x1D)  # #FAD61D
SEED_VERDE             = RGBColor(0x09, 0x84, 0x75)  # #098475

# Terciárias
SEED_CINZA             = RGBColor(0x61, 0x76, 0x83)  # #617683
SEED_AMARELO_DOURADO   = RGBColor(0xF9, 0xB1, 0x1C)  # #F9B11C
SEED_AZUL              = RGBColor(0x53, 0xC2, 0xE9)  # #53C2E9
SEED_AZUL_CLARO        = RGBColor(0xEC, 0xF4, 0xFC)  # #ECF4FC

# Derivadas oficiais
SEED_TURQUESA_DEEP     = RGBColor(0x0A, 0x84, 0x78)  # #0a8478
SEED_TURQUESA_SOFT     = RGBColor(0xE6, 0xF7, 0xF5)  # #e6f7f5
SEED_CINZA_LIGHT       = RGBColor(0xF4, 0xF6, 0xF7)  # #f4f6f7
SEED_CINZA_BORDER      = RGBColor(0xE1, 0xE6, 0xEA)  # #e1e6ea
SEED_TEXT              = RGBColor(0x2A, 0x39, 0x42)  # #2a3942

Slide canvas — sistema de coordenadas#

Slide 16:9 = 10 inches × 5.625 inches. Pensar como grid:

0,0────────────────────────────────────10,0
│  Safe zone:                            │
│  0.5" margem em todos os lados         │
│                                        │
│  Área útil: 9.0 × 4.625 inches         │
│                                        │
0,5.625──────────────────────────10,5.625

Safe zones (não negociáveis):

  • Margem mínima esquerda/direita: 0.5 inch
  • Margem mínima superior/inferior: 0.5 inch
  • Logo no rodapé: respeita 0.4" da borda inferior (não colar na borda)

Logo — regras de geometria#

Issue identificado em produção: logo cortada por bounding box apertada. Resolução: margem de segurança 10% do lado menor do logo em todas as direções dentro da bounding box.

# CERTO — bounding box com margem interna implícita
logo_left = Inches(0.5)
logo_top = Inches(0.4)
logo_width = Inches(1.5)   # margem 0.15" implícita
logo_height = Inches(0.45)
slide.shapes.add_picture(LOGO_PATH, logo_left, logo_top, logo_width, logo_height)

# ERRADO — bounding box justa, logo corta na renderização
slide.shapes.add_picture(LOGO_PATH, Inches(0.5), Inches(0.4),
                          Inches(1.2), Inches(0.36))  # justo demais

Tamanhos canônicos de logo por uso:

Uso Variante Width Height Posição
Capa (grande, centralizado) horizontal-fundo-turquesa.svg 4.0" 1.2" center horizontal, top 1.2"
Agradecimento (grande, centralizado) horizontal-fundo-turquesa.svg 4.0" 1.2" center horizontal, top 1.5"
Rodapé de slide intermediário símbolo (vertical-principal — só símbolo) 0.35" 0.35" right 0.5", bottom 0.4"
Slide de seção vertical-fundo-turquesa.svg 1.5" 1.5" bottom-right 0.6", 0.5"

10 layouts canônicos#

1. Capa#

Quando usar: sempre slide 1.

Dimensões:

# Fundo turquesa-deep
bg = slide.shapes.add_shape(MSO_SHAPE.RECTANGLE, 0, 0,
                              prs.slide_width, prs.slide_height)
bg.fill.solid()
bg.fill.fore_color.rgb = SEED_TURQUESA_DEEP
bg.line.fill.background()

# Logo horizontal grande, centralizado superior
logo = slide.shapes.add_picture(LOGO_FUNDO_TURQUESA, Inches(3.0), Inches(1.0),
                                  width=Inches(4.0), height=Inches(1.2))

# Título centralizado
title_box = slide.shapes.add_textbox(Inches(1.0), Inches(2.6),
                                       Inches(8.0), Inches(1.0))
tf = title_box.text_frame
tf.word_wrap = True
p = tf.paragraphs[0]
p.alignment = PP_ALIGN.CENTER
run = p.add_run()
run.text = "Título principal aqui"
run.font.name = "Montserrat"
run.font.size = Pt(44)
run.font.bold = True
run.font.color.rgb = BRANCO

# Subtítulo
sub_box = slide.shapes.add_textbox(Inches(1.0), Inches(3.7),
                                     Inches(8.0), Inches(0.6))
# (mesmo padrão, Pt(22), Light, branco)

Regras:

  • Fundo: turquesa-deep #0a8478 ou turquesa #11B0A0
  • Logo: horizontal-fundo-turquesa.svg, 4.0×1.2 inch, centralizado superior
  • Título: Montserrat Bold 44-54pt, branco, centralizado
  • Subtítulo: Montserrat Light 20-24pt, branco semi-transparente
  • Onda decorativa (opcional): SVG turquesa+verde na base do slide
  • Sem rodapé (capa é "limpa")

2. Seção / Divisor#

Quando usar: entre blocos de 3-5 slides, em decks de 15+ slides.

# Fundo turquesa
bg = slide.shapes.add_shape(MSO_SHAPE.RECTANGLE, 0, 0,
                              prs.slide_width, prs.slide_height)
bg.fill.solid()
bg.fill.fore_color.rgb = SEED_TURQUESA

# Número grande à esquerda
num_box = slide.shapes.add_textbox(Inches(0.8), Inches(1.5),
                                     Inches(2.5), Inches(2.5))
# Montserrat Bold 120pt, amarelo

# Título da seção à direita
title_box = slide.shapes.add_textbox(Inches(3.5), Inches(2.2),
                                       Inches(6.0), Inches(1.2))
# Montserrat Bold 36-44pt, branco

3. Conteúdo texto#

Default para texto/listas.

# Fundo branco
bg = slide.shapes.add_shape(MSO_SHAPE.RECTANGLE, 0, 0,
                              prs.slide_width, prs.slide_height)
bg.fill.solid()
bg.fill.fore_color.rgb = BRANCO
bg.line.fill.background()

# Header turquesa horizontal (faixa superior)
header = slide.shapes.add_shape(MSO_SHAPE.RECTANGLE, 0, 0,
                                  prs.slide_width, Inches(0.9))
header.fill.solid()
header.fill.fore_color.rgb = SEED_TURQUESA

# Título dentro do header
title_box = slide.shapes.add_textbox(Inches(0.5), Inches(0.2),
                                       Inches(9.0), Inches(0.5))
# Montserrat Bold 28-32pt, branco

# Body content abaixo do header
body_box = slide.shapes.add_textbox(Inches(0.5), Inches(1.2),
                                      Inches(9.0), Inches(3.8))
# Montserrat Regular 14-18pt, cinza
# Bullets ou parágrafos curtos

# Rodapé fino: símbolo direita + paginação
foot_logo = slide.shapes.add_picture(LOGO_SIMBOLO,
                                       Inches(9.15), Inches(5.25),
                                       Inches(0.35), Inches(0.35))

Regras:

  • Regra 6×6 — máximo 6 bullets × 6 palavras por bullet
  • Margens 0.5" mínimo
  • Não bullet-explodir: parágrafos curtos podem ser mais legíveis

4. Dados / Stat callout — CORRIGIDO#

Quando usar: destacar 1 a 3 números.

Bug histórico: layouts com múltiplos números sem coordenadas explícitas geravam overlay (número de 72pt cobrindo o label). Correção: declarar left/top/width/height para CADA elemento, e respeitar o espaço vertical do número (72pt ≈ 1.0 inch).

Layout canônico para 3 stats (grid horizontal 33/33/33):

# Fundo branco
bg = slide.shapes.add_shape(MSO_SHAPE.RECTANGLE, 0, 0,
                              prs.slide_width, prs.slide_height)
bg.fill.solid()
bg.fill.fore_color.rgb = BRANCO

# Título do slide (opcional, no topo)
title_box = slide.shapes.add_textbox(Inches(0.5), Inches(0.5),
                                       Inches(9.0), Inches(0.5))
# Montserrat Bold 24pt, turquesa

# Geometria das 3 colunas — IMPORTANTE: cada coluna tem 3 elementos verticais
# (número, linha separadora, label) cada um com seu retângulo distinto.
#
# Largura útil: 10.0 - 0.5 - 0.5 = 9.0 inches (3 colunas de 3.0 cada)
# Topo dos números: 1.7" (deixa espaço pro título acima)
# Altura do número (72pt fonte): 1.2"
# Topo da linha separadora: 3.0"
# Topo do label: 3.2"
# Topo do contexto: 3.8"

col_width = Inches(3.0)
col_lefts = [Inches(0.5), Inches(3.5), Inches(6.5)]

numbers = [("45.000 kWh", "CONSUMO MENSAL", "Indústria média região ES"),
           ("180 kVA", "DEMANDA CONTRATADA", "Grupo A4 cativo"),
           ("R$ 8.500", "ECONOMIA/MÊS", "Após otimização SEED")]

for i, (num, label, contexto) in enumerate(numbers):
    # NÚMERO grande
    n_box = slide.shapes.add_textbox(col_lefts[i], Inches(1.7),
                                       col_width, Inches(1.2))
    n_tf = n_box.text_frame
    n_tf.word_wrap = True
    n_p = n_tf.paragraphs[0]
    n_p.alignment = PP_ALIGN.CENTER
    n_run = n_p.add_run()
    n_run.text = num
    n_run.font.name = "Montserrat"
    n_run.font.size = Pt(48)  # 48-72pt — calibrar pelo tamanho do número
    n_run.font.bold = True
    n_run.font.color.rgb = SEED_TURQUESA

    # SEPARADOR linha curta (opcional, decorativo)
    sep = slide.shapes.add_shape(MSO_SHAPE.RECTANGLE,
                                   col_lefts[i] + Inches(1.25), Inches(3.05),
                                   Inches(0.5), Inches(0.03))
    sep.fill.solid()
    sep.fill.fore_color.rgb = SEED_CINZA_BORDER
    sep.line.fill.background()

    # LABEL UPPERCASE
    l_box = slide.shapes.add_textbox(col_lefts[i], Inches(3.2),
                                       col_width, Inches(0.4))
    l_tf = l_box.text_frame
    l_p = l_tf.paragraphs[0]
    l_p.alignment = PP_ALIGN.CENTER
    l_run = l_p.add_run()
    l_run.text = label
    l_run.font.name = "Montserrat"
    l_run.font.size = Pt(14)
    l_run.font.bold = True
    l_run.font.color.rgb = SEED_CINZA

    # CONTEXTO opcional
    c_box = slide.shapes.add_textbox(col_lefts[i], Inches(3.8),
                                       col_width, Inches(0.5))
    c_tf = c_box.text_frame
    c_p = c_tf.paragraphs[0]
    c_p.alignment = PP_ALIGN.CENTER
    c_run = c_p.add_run()
    c_run.text = contexto
    c_run.font.name = "Montserrat"
    c_run.font.size = Pt(11)
    c_run.font.color.rgb = SEED_CINZA

Tamanho do número por quantidade de stats:

Stats Tamanho do número Largura por coluna
1 stat (slide hero) 96pt (max 4.0" altura) 9.0" centralizado
2 stats 72pt (3.0" altura) 4.0" cada (gap 1.0")
3 stats 48-56pt (1.2-1.5" altura) 3.0" cada
4+ stats NÃO recomendado — quebrar em 2 slides

Anti-padrão verificado: colocar número 72pt + label + contexto em coluna de 2.0" — texto vaza horizontal. Largura mínima 3.0" pra número 48-72pt.

5. Gráfico#

Quando usar: dados comparativos, tendências, distribuições.

Geometria:

  • Título do slide: topo, 0.5" margem, altura 0.6"
  • Subtítulo (opcional): topo após título, 0.4"
  • Área do gráfico: 8.0×4.0 inches, centralizado, com 0.5" de margem
  • Fonte/legenda abaixo: Montserrat Light 10pt, cinza

Regras:

  • 1 chart por slide (não empilhar 2+)
  • Highlight de insight: uma cor SEED (geralmente turquesa) destaca o ponto crítico, resto neutro (SEED_CINZA ou SEED_CINZA_BORDER)
  • Não pintar tudo de turquesa — anula o destaque
  • Sempre incluir fonte citada (Aneel, EPE, IBGE, etc) no rodapé

6. Foto half-bleed#

Geometria:

  • Imagem: 5.0×5.625 inches (lado direito, full-bleed vertical)
  • Conteúdo lado esquerdo: 5.0×5.625 inches, fundo branco
    • Margem interna 0.5"
    • Título Montserrat Bold 24-32pt, turquesa
    • Body Montserrat Regular 14-18pt, cinza
    • Logo discreto no canto inferior do lado de texto

7. Comparativo (2 ou 3 colunas)#

Para 2 colunas (4.5×4.5 inches cada, gap 0.5"):

# Coluna 1
col1_bg = slide.shapes.add_shape(MSO_SHAPE.ROUNDED_RECTANGLE,
                                   Inches(0.5), Inches(1.3),
                                   Inches(4.5), Inches(3.6))
col1_bg.fill.solid()
col1_bg.fill.fore_color.rgb = SEED_TURQUESA_SOFT
col1_bg.line.color.rgb = SEED_CINZA_BORDER

# Header da coluna 1
col1_header = slide.shapes.add_shape(MSO_SHAPE.RECTANGLE,
                                       Inches(0.5), Inches(1.3),
                                       Inches(4.5), Inches(0.7))
col1_header.fill.solid()
col1_header.fill.fore_color.rgb = SEED_TURQUESA

# Título da coluna 1 dentro do header
# ... Montserrat Bold 18-22pt, branco

# Body da coluna 1 — bullets ou parágrafos
# ... Montserrat Regular 12-14pt, cinza ou text-dark

# Coluna 2 (lefts: 5.0", restante igual)

8. Citação / Depoimento#

# Fundo branco ou turquesa-soft
# Aspas grandes turquesa decorativas — em canto superior esquerdo
aspas_box = slide.shapes.add_textbox(Inches(0.5), Inches(0.6),
                                       Inches(1.0), Inches(1.5))
# " em Montserrat Bold 120pt, turquesa

# Texto da citação centralizado
quote_box = slide.shapes.add_textbox(Inches(1.5), Inches(1.5),
                                       Inches(7.0), Inches(2.5))
# Montserrat Regular 24-28pt, text-dark, itálico opcional

# Atribuição (autor + cargo)
author_box = slide.shapes.add_textbox(Inches(1.5), Inches(4.2),
                                       Inches(7.0), Inches(0.5))
# Montserrat SemiBold 14pt, cinza

9. Timeline#

Geometria horizontal:

# Linha central
line = slide.shapes.add_shape(MSO_SHAPE.RECTANGLE,
                                Inches(0.8), Inches(2.7),
                                Inches(8.4), Inches(0.06))
line.fill.solid()
line.fill.fore_color.rgb = SEED_TURQUESA

# Marcos: círculos numerados sobre a linha
# Para 5 marcos, espaçar a cada 2.0 inches a partir de 0.8"
marcos = ["2016", "2018", "2020", "2023", "2026"]
labels = ["Fundação", "Pri. cliente PJ", "Sede Vitória", "Diagnóstico 360°", "Lançamento ERP"]

for i, (data, lbl) in enumerate(zip(marcos, labels)):
    x = Inches(0.8 + i * 2.0)
    # Círculo
    circle = slide.shapes.add_shape(MSO_SHAPE.OVAL,
                                      x - Inches(0.2), Inches(2.5),
                                      Inches(0.4), Inches(0.4))
    circle.fill.solid()
    circle.fill.fore_color.rgb = SEED_TURQUESA

    # Data (acima ou abaixo, alternar)
    if i % 2 == 0:
        # Acima
        d_box = slide.shapes.add_textbox(x - Inches(0.6), Inches(1.7),
                                           Inches(1.2), Inches(0.3))
        lbl_box = slide.shapes.add_textbox(x - Inches(1.0), Inches(2.0),
                                             Inches(2.0), Inches(0.4))
    else:
        # Abaixo
        d_box = slide.shapes.add_textbox(x - Inches(0.6), Inches(3.0),
                                           Inches(1.2), Inches(0.3))
        lbl_box = slide.shapes.add_textbox(x - Inches(1.0), Inches(3.3),
                                             Inches(2.0), Inches(0.4))

10. Agradecimento / Fechamento#

Quando usar: sempre slide final.

# Fundo turquesa-deep
bg = slide.shapes.add_shape(MSO_SHAPE.RECTANGLE, 0, 0,
                              prs.slide_width, prs.slide_height)
bg.fill.solid()
bg.fill.fore_color.rgb = SEED_TURQUESA_DEEP

# Logo grande centralizado
logo = slide.shapes.add_picture(LOGO_FUNDO_TURQUESA,
                                  Inches(3.0), Inches(1.0),
                                  Inches(4.0), Inches(1.2))

# "Obrigado." ou similar
obg_box = slide.shapes.add_textbox(Inches(1.0), Inches(2.5),
                                     Inches(8.0), Inches(0.9))
# Montserrat Bold 48-64pt, branco, centralizado

# Contato — INCLUI 0800 SEMPRE
contato_box = slide.shapes.add_textbox(Inches(1.0), Inches(3.8),
                                         Inches(8.0), Inches(0.5))
# Montserrat Regular 18pt, branco, centralizado
# Texto: "seed.eng.br · 0800 591 5374"

# Tagline opcional
tagline_box = slide.shapes.add_textbox(Inches(1.0), Inches(4.6),
                                         Inches(8.0), Inches(0.5))
# Indie Flower 24pt, amarelo, centralizado
# Texto: "Provemos Eficiência Energética"

Regras:

  • 0800 591 5374 obrigatório no slide de fechamento (issue conhecido: decks anteriores foram apenas com site, perdendo canal imediato)
  • Logo grande centralizado (não no canto)
  • Onda decorativa na base (opcional)

Speaker notes — padrão#

Quando briefing inclui speaker notes:

slide.notes_slide.notes_text_frame.text = """
Pontos pra falar neste slide:
- [Contexto que apoia o que está visível]
- [Exemplo ou case mencionado em voz]
- [Transição pro próximo slide]
"""

Speaker notes são pra Rafael falar, plateia não vê. Permite slide enxuto (1 takeaway visual) com narrativa rica na fala.

Restrições visuais (anti-AI-slop, alinhado com pptx oficial)#

  • ❌ Sem accent lines sob títulos (hallmark de slides AI-generated)
  • ❌ Sem decorative full-width colored bars como rodapé (rodapé SEED é fino, com símbolo)
  • ❌ Sem slides text-only (sempre EEny, ondas, ícone Lucide ou gráfico complementando)
  • ❌ Sem cream/beige como fundo (branco ou cores SEED apenas)
  • ❌ Sem mais de 1 chart por slide
  • ❌ Sem text overflow (validar via QA da pptx skill)
  • ❌ Sem elementos sem geometria explícita (left, top, width, height obrigatórios)
  • ❌ Sem logo com bounding box justa (margem 10% interna mínima)
  • ❌ Sem stat callout com números 72pt em coluna <3.0" (vaza horizontalmente)

Checklist de QA visual após geração#

Antes de entregar, verificar nos JPGs renderizados:

  • [ ] Logo aparece COMPLETA (não cortada nas bordas da bounding box)
  • [ ] Stat callout: NÚMEROS e LABELS não se sobrepõem (verificar 1.5"+ entre topo do número e topo do label)
  • [ ] Margens 0.5" respeitadas em todos os lados
  • [ ] Nenhum texto vaza da bounding box
  • [ ] Rodapé: símbolo SEED no canto direito (não decorative bar)
  • [ ] Capa: logo 4.0×1.2" centralizado, não cortado
  • [ ] Agradecimento: contém "0800 591 5374"
  • [ ] Paleta: cores 100% SEED (18 tokens), zero hex alheio
  • [ ] Grafia "SEED engenharia" correta em todos os elementos visíveis

Esc