feat(design-media): adiciona plugin design-media (agents, skills, knowledge e metadados do projeto)
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
# AGENTS.md — skills
|
||||
|
||||
Directrizes específicas deste projecto para agentes IA.
|
||||
|
||||
## Referências obrigatórias
|
||||
|
||||
- `ECOSYSTEM.md` — Hub/06-Operacoes/Documentacao/ECOSYSTEM.md
|
||||
- `PROC-DEV-STANDARD` — D7-SIS-006
|
||||
- `PROC-AUDIT-STANDARD` — D7-SIS-007
|
||||
|
||||
## Protocolo de sessão
|
||||
|
||||
Início: ler MEMORY.md + STATUS.md. Fim: actualizar ambos.
|
||||
|
||||
## Convenções específicas
|
||||
|
||||
- (a definir)
|
||||
@@ -0,0 +1,5 @@
|
||||
# CHANGELOG — skills
|
||||
|
||||
## 0.1.0 — 2026-06-30
|
||||
### Adicionado
|
||||
- Estrutura padrão (PROC-DEV-STANDARD)
|
||||
@@ -0,0 +1,4 @@
|
||||
# MEMORY.md — skills
|
||||
|
||||
## 2026-06-30
|
||||
- Estrutura padrão aplicada via propagate-structure.sh
|
||||
@@ -0,0 +1,3 @@
|
||||
# skills
|
||||
|
||||
Subprojecto skills do ecossistema Descomplicar.
|
||||
@@ -0,0 +1,8 @@
|
||||
# STATUS.md — skills
|
||||
|
||||
**Versão:** 0.1 | **Data:** 2026-06-30 | **Agente:** —
|
||||
|
||||
## Estado actual
|
||||
- Em curso: —
|
||||
- Bloqueios: —
|
||||
- Próximos passos: —
|
||||
@@ -0,0 +1,160 @@
|
||||
---
|
||||
name: brand-guidelines
|
||||
description: Guia de identidade visual Descomplicar® — cores, tipografia, logotipo, tom de comunicacao e aplicacao por contexto (slides, docs, web, emails). Usar quando "brand descomplicar", "marca descomplicar", "cores descomplicar", "identidade visual", "branding", "paleta de cores", "guia de marca", ou qualquer material que necessite conformidade visual com a marca.
|
||||
layer: wiki
|
||||
---
|
||||
|
||||
# /brand-guidelines - Identidade Visual Descomplicar®
|
||||
|
||||
Referencia normativa da marca Descomplicar®. Aplicar em todos os materiais de comunicacao,
|
||||
design e desenvolvimento.
|
||||
|
||||
---
|
||||
|
||||
## Identidade da Marca
|
||||
|
||||
**Nome oficial:** Descomplicar®
|
||||
**Slogan:** Crescimento Digital
|
||||
**Website:** descomplicar.pt
|
||||
**Tom:** Profissional mas acessivel, tecnologico sem ser frio
|
||||
**Valores:** Simplicidade, transparencia, resultados mensuraveis
|
||||
|
||||
> A marca registada (®) e obrigatoria na primeira ocorrencia em qualquer documento ou comunicacao.
|
||||
> Nas ocorrencias seguintes, pode usar-se apenas "Descomplicar".
|
||||
|
||||
---
|
||||
|
||||
## Paleta de Cores Principal
|
||||
|
||||
| Nome | Hex | RGB | Uso |
|
||||
|------|-----|-----|-----|
|
||||
| Azul Escuro | `#1a365d` | 26, 54, 93 | Texto principal, fundos escuros, cabecalhos |
|
||||
| Azul Medio | `#2b6cb0` | 43, 108, 176 | Links, acentos, botoes secundarios |
|
||||
| Laranja | `#dd6b20` | 221, 107, 32 | CTA, destaques, elementos de accao |
|
||||
| Branco | `#ffffff` | 255, 255, 255 | Fundos claros, texto sobre escuro |
|
||||
| Cinza Claro | `#f7fafc` | 247, 250, 252 | Fundos secundarios, secoes alternadas |
|
||||
| Cinza Texto | `#4a5568` | 74, 85, 104 | Texto de corpo, descricoes |
|
||||
|
||||
Paleta completa com variacoes de contexto: `references/color-palettes.md`
|
||||
|
||||
---
|
||||
|
||||
## CSS Variables (Web)
|
||||
|
||||
```css
|
||||
:root {
|
||||
/* Cores principais */
|
||||
--color-primary: #1a365d;
|
||||
--color-secondary: #2b6cb0;
|
||||
--color-accent: #dd6b20;
|
||||
|
||||
/* Neutros */
|
||||
--color-white: #ffffff;
|
||||
--color-bg-light: #f7fafc;
|
||||
--color-text-body: #4a5568;
|
||||
--color-text-heading: #1a365d;
|
||||
|
||||
/* Estados */
|
||||
--color-primary-hover: #2a4a7f;
|
||||
--color-secondary-hover: #2c5282;
|
||||
--color-accent-hover: #c05621;
|
||||
|
||||
/* Bordas e divisores */
|
||||
--color-border: #e2e8f0;
|
||||
--color-border-light: #edf2f7;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Tipografia
|
||||
|
||||
### Hierarquia
|
||||
|
||||
| Elemento | Familia | Peso | Tamanho base |
|
||||
|----------|---------|------|--------------|
|
||||
| H1 / Titulo principal | Montserrat | Extra Bold (800) | 48px / 3rem |
|
||||
| H2 / Titulo secao | Montserrat | Bold (700) | 36px / 2.25rem |
|
||||
| H3 / Subtitulo | Montserrat | Semi Bold (600) | 24px / 1.5rem |
|
||||
| H4 / Label | Montserrat | Semi Bold (600) | 18px / 1.125rem |
|
||||
| Corpo / Paragrafo | Open Sans | Regular (400) | 16px / 1rem |
|
||||
| Destaque / Lead | Open Sans | Semi Bold (600) | 18px / 1.125rem |
|
||||
| Legenda / Caption | Open Sans | Regular (400) | 14px / 0.875rem |
|
||||
| Codigo | JetBrains Mono | Regular (400) | 14px / 0.875rem |
|
||||
|
||||
### CSS Tipografia
|
||||
|
||||
```css
|
||||
:root {
|
||||
--font-heading: 'Montserrat', 'Arial Black', sans-serif;
|
||||
--font-body: 'Open Sans', 'Helvetica Neue', Arial, sans-serif;
|
||||
--font-code: 'JetBrains Mono', 'Fira Code', 'Courier New', monospace;
|
||||
|
||||
--line-height-heading: 1.2;
|
||||
--line-height-body: 1.6;
|
||||
--letter-spacing-heading: -0.025em;
|
||||
}
|
||||
```
|
||||
|
||||
### Fallbacks de Sistema
|
||||
|
||||
- **Montserrat** indisponivel: `'Arial Black', 'Impact', sans-serif`
|
||||
- **Open Sans** indisponivel: `'Helvetica Neue', Arial, sans-serif`
|
||||
- **JetBrains Mono** indisponivel: `'Fira Code', 'Courier New', monospace`
|
||||
|
||||
---
|
||||
|
||||
## Logótipo
|
||||
|
||||
### Regras de Uso
|
||||
|
||||
| Regra | Descricao |
|
||||
|-------|-----------|
|
||||
| Espaco minimo | Margem de pelo menos 2x a altura da letra "D" em todos os lados |
|
||||
| Tamanho minimo | 120px de largura em digital; 30mm em impressao |
|
||||
| Fundo permitido | Branco `#ffffff`, Azul Escuro `#1a365d`, Cinza Claro `#f7fafc` |
|
||||
| Fundo proibido | Qualquer fundo com baixo contraste, fotografias sem overlay |
|
||||
| Distorcao | Nunca esticar, rodar ou alterar proporcoes |
|
||||
| Cores proibidas | Nunca alterar as cores do logótipo original |
|
||||
| Texto junto | Nunca sobrepor texto ao logótipo |
|
||||
|
||||
### Variantes Disponiveis
|
||||
|
||||
| Variante | Quando usar |
|
||||
|----------|-------------|
|
||||
| Principal (horizontal) | Uso geral, cabecalhos, documentos |
|
||||
| Compacta (icone + nome vertical) | Espacos reduzidos, avatares |
|
||||
| Monocromatica escura | Documentos a preto e branco, impressao simples |
|
||||
| Monocromatica clara | Sobre fundos escuros, rodapes |
|
||||
| Icone isolado | Favicon, app icon, redes sociais (foto de perfil) |
|
||||
|
||||
### Ficheiros Logótipo
|
||||
|
||||
```
|
||||
Hub/04-Recursos/Design/brands/descomplicar/
|
||||
logo-principal.svg
|
||||
logo-compacto.svg
|
||||
logo-mono-escuro.svg
|
||||
logo-mono-claro.svg
|
||||
favicon.png
|
||||
favicon.svg
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Aplicacao por Contexto
|
||||
|
||||
### Apresentacoes e Slides
|
||||
|
||||
```
|
||||
Fundo slides: #1a365d (escuro) ou #ffffff (claro)
|
||||
Titulo slide: Montserrat Extra Bold, #ffffff (sobre escuro) / #1a365d (sobre claro)
|
||||
Corpo texto: Open Sans Regular, #ffffff ou #4a5568
|
||||
Destaques/CTA: #dd6b20
|
||||
Divisores: #2b6cb0
|
||||
Slide titulo (capa): fundo #1a365d, logótipo variante clara
|
||||
```
|
||||
|
||||
Modelo: `/design presentation --brand descomplicar`
|
||||
|
||||
##
|
||||
@@ -0,0 +1,227 @@
|
||||
# Paletas de Cores Descomplicar® — Referencia Detalhada
|
||||
|
||||
Extensao de `brand-guidelines/SKILL.md`. Paletas completas com variacoes de contexto,
|
||||
estados de interaccao e combinacoes aprovadas.
|
||||
|
||||
---
|
||||
|
||||
## Paleta Principal
|
||||
|
||||
| Token | Hex | RGB | HSL |
|
||||
|-------|-----|-----|-----|
|
||||
| `--color-primary` | `#1a365d` | 26, 54, 93 | 213°, 56%, 23% |
|
||||
| `--color-secondary` | `#2b6cb0` | 43, 108, 176 | 211°, 61%, 43% |
|
||||
| `--color-accent` | `#dd6b20` | 221, 107, 32 | 27°, 74%, 50% |
|
||||
| `--color-white` | `#ffffff` | 255, 255, 255 | — |
|
||||
| `--color-bg-light` | `#f7fafc` | 247, 250, 252 | 204°, 33%, 98% |
|
||||
| `--color-text-body` | `#4a5568` | 74, 85, 104 | 220°, 17%, 35% |
|
||||
|
||||
---
|
||||
|
||||
## Escala Azul Escuro (Primary)
|
||||
|
||||
| Variacao | Hex | Uso |
|
||||
|----------|-----|-----|
|
||||
| 50 (mais claro) | `#ebf4ff` | Fundos hover muito suaves |
|
||||
| 100 | `#dbeafe` | Fundos informativos |
|
||||
| 200 | `#bfdbfe` | Bordas suaves |
|
||||
| 300 | `#93c5fd` | Icones em fundo claro |
|
||||
| 400 | `#60a5fa` | Interaccao hover em elementos claros |
|
||||
| 500 | `#2b6cb0` | Azul medio (secondary) |
|
||||
| 600 | `#1d4ed8` | Links hover |
|
||||
| 700 | `#1e40af` | Botoes primarios hover |
|
||||
| 800 | `#1e3a8a` | Variacao escura |
|
||||
| **900 (base)** | `#1a365d` | **Cor primaria — uso principal** |
|
||||
|
||||
---
|
||||
|
||||
## Escala Laranja (Accent)
|
||||
|
||||
| Variacao | Hex | Uso |
|
||||
|----------|-----|-----|
|
||||
| 50 | `#fff7ed` | Fundo callout de atencao |
|
||||
| 100 | `#ffedd5` | Destaque suave |
|
||||
| 200 | `#fed7aa` | Borda callout |
|
||||
| 300 | `#fdba74` | Icones de alerta em fundo claro |
|
||||
| 400 | `#fb923c` | Hover em elementos de acento |
|
||||
| **500 (base)** | `#dd6b20` | **Cor de acento — CTA principal** |
|
||||
| 600 | `#c05621` | Hover botao CTA |
|
||||
| 700 | `#9c4221` | Pressed state / active |
|
||||
| 800 | `#7c2d12` | Texto sobre fundo laranja claro |
|
||||
|
||||
---
|
||||
|
||||
## Escala de Neutros
|
||||
|
||||
| Token | Hex | Uso |
|
||||
|-------|-----|-----|
|
||||
| Branco | `#ffffff` | Fundos principais, texto sobre escuro |
|
||||
| Gray 50 | `#f7fafc` | Fundos secundarios, seccoes alternadas |
|
||||
| Gray 100 | `#edf2f7` | Hover em items de lista |
|
||||
| Gray 200 | `#e2e8f0` | Bordas, divisores |
|
||||
| Gray 300 | `#cbd5e0` | Bordas de formularios desactivados |
|
||||
| Gray 400 | `#a0aec0` | Placeholder text, icones inactivos |
|
||||
| Gray 500 | `#718096` | Texto auxiliar, labels |
|
||||
| **Gray 600** | `#4a5568` | **Texto de corpo principal** |
|
||||
| Gray 700 | `#2d3748` | Texto secundario escuro |
|
||||
| Gray 800 | `#1a202c` | Texto titulo alternativo |
|
||||
| Gray 900 | `#171923` | Fundo ultra-escuro (raro) |
|
||||
|
||||
---
|
||||
|
||||
## Combinacoes de Cor Aprovadas
|
||||
|
||||
### Combinacoes de Alta Prioridade (CTA e Heroi)
|
||||
|
||||
| Fundo | Texto / Elemento | Racio | Nota |
|
||||
|-------|-----------------|-------|------|
|
||||
| `#1a365d` | `#ffffff` | 12.6:1 | Preferencial — hero, capa, footer |
|
||||
| `#2b6cb0` | `#ffffff` | 5.1:1 | Botoes, badges, chips |
|
||||
| `#dd6b20` | `#ffffff` | 3.1:1 | CTA (apenas texto grande >=18px ou bold >=14px) |
|
||||
| `#ffffff` | `#1a365d` | 12.6:1 | Documentos, corpo pagina |
|
||||
| `#f7fafc` | `#1a365d` | 11.9:1 | Cards, seccoes alternadas |
|
||||
|
||||
### Combinacoes de Texto (Corpo)
|
||||
|
||||
| Fundo | Texto | Racio | Nivel WCAG |
|
||||
|-------|-------|-------|-----------|
|
||||
| `#ffffff` | `#4a5568` | 7.0:1 | AAA |
|
||||
| `#f7fafc` | `#4a5568` | 6.6:1 | AAA |
|
||||
| `#ffffff` | `#2d3748` | 10.7:1 | AAA |
|
||||
| `#1a365d` | `#f7fafc` | 12.0:1 | AAA |
|
||||
|
||||
### Combinacoes Proibidas
|
||||
|
||||
| Fundo | Texto | Motivo |
|
||||
|-------|-------|--------|
|
||||
| `#dd6b20` | `#ffffff` | Contraste insuficiente para texto pequeno (3.1:1) |
|
||||
| `#2b6cb0` | `#1a365d` | Contraste insuficiente entre tons de azul (2.2:1) |
|
||||
| `#4a5568` | `#2b6cb0` | Baixo contraste em textos de corpo (2.8:1) |
|
||||
| Qualquer cor | `#a0aec0` | Gray 400 nunca como texto (max 2.9:1 sobre branco) |
|
||||
|
||||
---
|
||||
|
||||
## Paleta por Contexto de Produto
|
||||
|
||||
### Dashboard / Aplicacao Web
|
||||
|
||||
```
|
||||
Sidebar: fundo #1a365d, icones #f7fafc (inactivo), #dd6b20 (activo)
|
||||
Top bar: fundo #ffffff, borda inferior #e2e8f0
|
||||
Conteudo: fundo #f7fafc
|
||||
Cards: fundo #ffffff, sombra --shadow-sm
|
||||
Tabelas: linhas alternas #f7fafc / #ffffff
|
||||
Botao primario: #dd6b20 (fundo), #ffffff (texto)
|
||||
Botao secundario: #2b6cb0 (borda e texto), transparente (fundo)
|
||||
Botao ghost: #4a5568 (texto), hover #f7fafc (fundo)
|
||||
Links inline: #2b6cb0, hover #1a365d
|
||||
```
|
||||
|
||||
### Apresentacoes (Slides)
|
||||
|
||||
```
|
||||
Slide escuro (capa, divider): fundo #1a365d
|
||||
- Titulo: Montserrat 800, #ffffff
|
||||
- Subtitulo: Montserrat 600, #f7fafc
|
||||
- Acento barra: #dd6b20
|
||||
- Logótipo: variante clara
|
||||
|
||||
Slide claro (conteudo): fundo #ffffff
|
||||
- Titulo: Montserrat 700, #1a365d
|
||||
- Corpo: Open Sans 400, #4a5568
|
||||
- Highlight box: fundo #f7fafc, borda esquerda #dd6b20 4px
|
||||
- Numero/stat: Montserrat 800, #dd6b20 ou #2b6cb0
|
||||
|
||||
Slide citacao: fundo #f7fafc
|
||||
- Aspas: #dd6b20
|
||||
- Texto citacao: Montserrat 600, #1a365d
|
||||
- Atribuicao: Open Sans 400, #4a5568
|
||||
```
|
||||
|
||||
### Email Marketing
|
||||
|
||||
```
|
||||
Wrapper: fundo #f7fafc
|
||||
Container: fundo #ffffff, max-width 600px
|
||||
Pre-header (top bar): fundo #1a365d, altura 4px ou bloco com logótipo
|
||||
Header: fundo #1a365d, logótipo clara, padding 32px
|
||||
Titulo: Montserrat 700, #ffffff, 28px
|
||||
Body: fundo #ffffff, padding 32px
|
||||
H2: Montserrat 600, #1a365d, 22px
|
||||
Paragrafo: Open Sans 400, #4a5568, 16px, line-height 1.6
|
||||
Link inline: #2b6cb0
|
||||
CTA block: centrado, botao #dd6b20, texto #ffffff, border-radius 4px, padding 14px 28px
|
||||
Divisor: border-top 1px solid #e2e8f0
|
||||
Footer: fundo #f7fafc, texto #718096, 13px, links #4a5568
|
||||
```
|
||||
|
||||
### Social Media
|
||||
|
||||
```
|
||||
Post Instagram (1080x1080):
|
||||
Opcao A (escuro): fundo #1a365d, titulo #ffffff, acento #dd6b20
|
||||
Opcao B (claro): fundo #ffffff, titulo #1a365d, detalhe #dd6b20
|
||||
Borda/frame: strip #dd6b20 (8-12px) em baixo ou em cima
|
||||
Logo: canto inferior direito, variante adequada ao fundo
|
||||
|
||||
Story Instagram (1080x1920):
|
||||
Gradiente vertical: #1a365d (topo) -> #2b6cb0 (base)
|
||||
Texto: #ffffff
|
||||
CTA button area: #dd6b20
|
||||
|
||||
LinkedIn Banner (1584x396):
|
||||
Fundo: #1a365d ou fotografia com overlay #1a365d 60%
|
||||
Texto: #ffffff (titulo), #f7fafc (sub)
|
||||
Acento: strip ou elemento #dd6b20
|
||||
```
|
||||
|
||||
### Documentos PDF / Propostas
|
||||
|
||||
```
|
||||
Capa: fundo #1a365d
|
||||
Logo: variante clara, centrado no topo
|
||||
Titulo: Montserrat 800, #ffffff, 36px
|
||||
Subtitulo: Montserrat 400, #f7fafc, 18px
|
||||
Data/ref: Open Sans 400, #a0aec0, 14px, em baixo
|
||||
|
||||
Paginas internas:
|
||||
Cabecalho: altura 48px, fundo #1a365d, logótipo pequena (variante clara), numero de pagina
|
||||
Titulo capitulo: Montserrat 700, #1a365d, 22px, fundo #f7fafc, padding 12px, borda esquerda #dd6b20 4px
|
||||
Corpo: Open Sans 400, #4a5568, 11pt, line-height 1.6
|
||||
Callout/destaque: fundo #f7fafc, borda #dd6b20, icone #dd6b20
|
||||
Tabelas: header fundo #1a365d texto #ffffff; linhas alternas #f7fafc / #ffffff
|
||||
Rodape: borda topo #e2e8f0, texto #718096, 9pt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Gradientes Aprovados
|
||||
|
||||
| Nome | Valor CSS | Uso |
|
||||
|------|-----------|-----|
|
||||
| Hero primario | `linear-gradient(135deg, #1a365d 0%, #2b6cb0 100%)` | Heroi web, fundo apresentacao |
|
||||
| Acento | `linear-gradient(135deg, #dd6b20 0%, #f6ad55 100%)` | Banners promocionais |
|
||||
| Escuro suave | `linear-gradient(180deg, #1a365d 0%, #2d3748 100%)` | Sidebars, overlays |
|
||||
| Claro | `linear-gradient(180deg, #ffffff 0%, #f7fafc 100%)` | Seccoes de transicao |
|
||||
|
||||
> Nunca usar gradientes em texto (excecto como elemento decorativo com contraste garantido).
|
||||
> Maximo 2 gradientes por composicao visual.
|
||||
|
||||
---
|
||||
|
||||
## Cores de Estado e Feedback
|
||||
|
||||
| Estado | Cor | Hex | Uso |
|
||||
|--------|-----|-----|-----|
|
||||
| Sucesso | Verde | `#38a169` | Confirmacoes, checkmarks, alertas positivos |
|
||||
| Aviso | Amarelo | `#d69e2e` | Alertas de atencao, pendentes |
|
||||
| Erro | Vermelho | `#e53e3e` | Erros, validacoes negativas |
|
||||
| Informacao | Azul Medio | `#2b6cb0` | Mensagens informativas, tooltips |
|
||||
|
||||
> Cores de estado nao fazem parte da identidade visual principal.
|
||||
> Usar apenas para feedback de interface, nunca como cor de marca.
|
||||
|
||||
---
|
||||
|
||||
*Referencia de paletas v1.0.0 | 2026-03-10 | Descomplicar®*
|
||||
*Fonte principal: `brand-guidelines/SKILL.md`*
|
||||
@@ -0,0 +1,155 @@
|
||||
---
|
||||
name: "Descomplicar Digital"
|
||||
description: "Professional technology consulting theme with warm accents"
|
||||
version: "1.0.0"
|
||||
updated: "2026-03-10"
|
||||
layer: wiki
|
||||
---
|
||||
|
||||
# Tema Descomplicar Digital
|
||||
|
||||
Tema oficial Descomplicar® para uso em apresentações, relatórios, designs e qualquer material de comunicação.
|
||||
|
||||
---
|
||||
|
||||
## Paleta de Cores
|
||||
|
||||
```yaml
|
||||
colors:
|
||||
primary: "#1a365d" # Azul escuro — headers, fundos principais
|
||||
secondary: "#2b6cb0" # Azul médio — links, sub-headers
|
||||
accent: "#dd6b20" # Laranja — CTAs, destaques, números
|
||||
background: "#ffffff" # Branco — fundo principal
|
||||
surface: "#f7fafc" # Cinza muito claro — secções alternadas
|
||||
text_primary: "#2d3748" # Cinza escuro — texto corpo
|
||||
text_secondary: "#4a5568" # Cinza médio — subtítulos, legendas
|
||||
border: "#e2e8f0" # Cinza claro — bordas, separadores
|
||||
success: "#38a169" # Verde — confirmações
|
||||
warning: "#d69e2e" # Amarelo — avisos
|
||||
error: "#e53e3e" # Vermelho — erros
|
||||
```
|
||||
|
||||
### Referência Visual
|
||||
|
||||
| Token | Hex | Uso |
|
||||
|-------|-----|-----|
|
||||
| `primary` | `#1a365d` | Headers H1/H2, fundos de navegação, capa de apresentação |
|
||||
| `secondary` | `#2b6cb0` | Links, H3/H4, badges, ícones activos |
|
||||
| `accent` | `#dd6b20` | Botões CTA, números em destaque, linhas de separação principais |
|
||||
| `background` | `#ffffff` | Fundo padrão de slides e páginas |
|
||||
| `surface` | `#f7fafc` | Slides alternados, tabelas linha par, painéis laterais |
|
||||
| `text_primary` | `#2d3748` | Corpo de texto, parágrafos, listas |
|
||||
| `text_secondary` | `#4a5568` | Subtítulos, legendas, texto auxiliar |
|
||||
| `border` | `#e2e8f0` | Bordas de tabela, separadores horizontais, cards |
|
||||
| `success` | `#38a169` | Confirmações, métricas positivas, status "concluído" |
|
||||
| `warning` | `#d69e2e` | Avisos, métricas de atenção, status "em risco" |
|
||||
| `error` | `#e53e3e` | Erros, métricas negativas, status "crítico" |
|
||||
|
||||
---
|
||||
|
||||
## Tipografia
|
||||
|
||||
```yaml
|
||||
fonts:
|
||||
heading: "Montserrat"
|
||||
heading_weight: "700, 800"
|
||||
heading_fallback: "Arial, sans-serif"
|
||||
body: "Open Sans"
|
||||
body_weight: "400, 600"
|
||||
body_fallback: "Helvetica, sans-serif"
|
||||
code: "JetBrains Mono"
|
||||
code_fallback: "Consolas, monospace"
|
||||
```
|
||||
|
||||
### Hierarquia Tipográfica
|
||||
|
||||
| Nível | Fonte | Peso | Tamanho (slides) | Tamanho (docs) |
|
||||
|-------|-------|------|-----------------|----------------|
|
||||
| H1 — Título principal | Montserrat | 800 | 40-48px | 32px |
|
||||
| H2 — Título secção | Montserrat | 700 | 28-36px | 24px |
|
||||
| H3 — Subtítulo | Montserrat | 700 | 22-26px | 20px |
|
||||
| H4 — Label | Open Sans | 600 | 18-20px | 16px |
|
||||
| Corpo | Open Sans | 400 | 16-18px | 14-16px |
|
||||
| Caption | Open Sans | 400 | 12-14px | 12px |
|
||||
| Código | JetBrains Mono | 400 | 14-16px | 13px |
|
||||
|
||||
### Google Fonts — Import
|
||||
|
||||
```css
|
||||
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@700;800&family=Open+Sans:wght@400;600&family=JetBrains+Mono&display=swap');
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Regras de Uso
|
||||
|
||||
```yaml
|
||||
usage_notes:
|
||||
- Usar laranja com moderação (apenas CTAs e destaques-chave)
|
||||
- Azul escuro para headers e elementos de navegação
|
||||
- Fundos alternados branco/cinza para secções longas
|
||||
- Nunca usar mais de 3 cores numa slide
|
||||
- Manter contraste WCAG AA em todos os textos
|
||||
```
|
||||
|
||||
### Regras Expandidas
|
||||
|
||||
**Cores**
|
||||
- O laranja (`accent`) é reservado para no máximo 1-2 elementos por slide/página
|
||||
- Nunca usar `primary` e `accent` em simultâneo em texto — garante legibilidade
|
||||
- Fundo `surface` em slides alternados cria ritmo visual sem poluição
|
||||
- Combinação permitida em texto: `primary` fundo + `background` texto, ou `background` fundo + `primary` texto
|
||||
|
||||
**Tipografia**
|
||||
- Nunca misturar Montserrat com outra fonte de títulos no mesmo documento
|
||||
- Open Sans é a única fonte de corpo permitida
|
||||
- Código inline e blocos de código: sempre JetBrains Mono
|
||||
- Não usar itálico em títulos — usar peso (bold) para ênfase
|
||||
|
||||
**Contraste WCAG AA**
|
||||
- `text_primary` (#2d3748) sobre `background` (#ffffff): rácio 12.6:1 — aprovado
|
||||
- `text_secondary` (#4a5568) sobre `background` (#ffffff): rácio 7.4:1 — aprovado
|
||||
- `accent` (#dd6b20) sobre `background` (#ffffff): rácio 3.8:1 — aprovado para texto grande (>18px bold)
|
||||
- `background` (#ffffff) sobre `primary` (#1a365d): rácio 12.6:1 — aprovado
|
||||
|
||||
---
|
||||
|
||||
## Aplicação em Slides
|
||||
|
||||
### Layout Tipo Capa
|
||||
|
||||
```
|
||||
[Fundo: primary #1a365d]
|
||||
[Logo Descomplicar — branco, topo esquerdo]
|
||||
[H1: Montserrat 800, branco]
|
||||
[H2: Montserrat 700, accent #dd6b20]
|
||||
[Rodapé: Open Sans 400, text_secondary, separador border]
|
||||
```
|
||||
|
||||
### Layout Tipo Conteúdo
|
||||
|
||||
```
|
||||
[Fundo: background #ffffff]
|
||||
[Header barra: primary #1a365d, 8px altura]
|
||||
[H2: primary #1a365d, Montserrat 700]
|
||||
[Corpo: text_primary #2d3748, Open Sans 400]
|
||||
[Sidebar ou destaque: surface #f7fafc]
|
||||
[CTA ou número chave: accent #dd6b20, Montserrat 800]
|
||||
```
|
||||
|
||||
### Layout Tipo Dados / Métricas
|
||||
|
||||
```
|
||||
[Fundo alternado: surface #f7fafc]
|
||||
[Número grande: accent #dd6b20, Montserrat 800, 60-80px]
|
||||
[Label: text_secondary #4a5568, Open Sans 600, 14px]
|
||||
[Ícone: secondary #2b6cb0]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Aplicação em HTML (Desk CRM / Relatórios)
|
||||
|
||||
```css
|
||||
:root {
|
||||
--c
|
||||
@@ -0,0 +1,105 @@
|
||||
---
|
||||
name: cinematic-site
|
||||
category: design-media
|
||||
description: "Constroi websites cinematograficos a partir de um site existente. Pipeline 4 passos: brand analysis, scene generation, build HTML/CSS, preview. Usar quando 'cinematic', 'website premium', 'site cinematografico', 'redesign site', 'nanobanana'."
|
||||
version: "1.0.0"
|
||||
created: 2026-04-07
|
||||
tools: [Bash, Read, Write, mcp__claude-in-chrome__read_page, mcp__claude-in-chrome__tabs_create_mcp, mcp__chrome-devtools__take_screenshot]
|
||||
layer: wiki
|
||||
---
|
||||
|
||||
# Skill: /cinematic-site
|
||||
|
||||
Constroi websites cinematograficos responsivos a partir de um site existente. Inspirado no Nanobanana 2 (#366 Jay E / RoboNuggets).
|
||||
|
||||
---
|
||||
|
||||
## Pipeline de 4 passos
|
||||
|
||||
### Passo 1 — Brand Analysis
|
||||
|
||||
Receber URL do site existente do utilizador.
|
||||
|
||||
1. Abrir URL via `mcp__claude-in-chrome__tabs_create_mcp` + `mcp__claude-in-chrome__read_page`
|
||||
2. Extrair:
|
||||
- Paleta de cores (hex codes das cores dominantes)
|
||||
- Logo (URL ou descricao)
|
||||
- Fontes usadas (font-family do CSS)
|
||||
- Tom de voz (formal, casual, tecnico)
|
||||
- Tipo de negocio e sector
|
||||
- Conteudo principal (hero text, servicos, about)
|
||||
3. Guardar analise em `/tmp/cinematic-site/brand-analysis.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"url": "https://...",
|
||||
"business": "restaurante italiano",
|
||||
"colors": {"primary": "#2C3E50", "secondary": "#E74C3C", "accent": "#F39C12"},
|
||||
"fonts": {"heading": "Playfair Display", "body": "Inter"},
|
||||
"tone": "acolhedor e premium",
|
||||
"logo_description": "...",
|
||||
"hero_text": "...",
|
||||
"sections": ["sobre", "menu", "reservas", "contacto"]
|
||||
}
|
||||
```
|
||||
|
||||
### Passo 2 — Scene Generation
|
||||
|
||||
Com base na analise, definir o design cinematografico:
|
||||
|
||||
1. **Hero section:** escolher tipo de animacao:
|
||||
- Parallax com imagem de fundo
|
||||
- Scroll-reveal progressivo
|
||||
- Video background concept (descricao, nao video real)
|
||||
- Cursor-follow effect
|
||||
2. **3-5 seccoes adicionais** com animacoes scroll-based:
|
||||
- Referenciar `Hub/04-Stack/02.03-IA/biblioteca-animacoes-scroll.md` para patterns disponiveis
|
||||
3. **Responsive breakpoints:** mobile-first, 3 breakpoints (mobile, tablet, desktop)
|
||||
4. Guardar plano em `/tmp/cinematic-site/scene-plan.md`
|
||||
|
||||
### Passo 3 — Build
|
||||
|
||||
Gerar ficheiros HTML/CSS/JS:
|
||||
|
||||
1. Criar `/tmp/cinematic-site/output/`:
|
||||
- `index.html` — single-page com todas as seccoes
|
||||
- `styles.css` — Tailwind ou CSS puro
|
||||
- `animations.js` — scroll observers + animacoes
|
||||
2. Regras de qualidade:
|
||||
- Referenciar `design.json` Descomplicar para standards
|
||||
- Mobile-first
|
||||
- Core Web Vitals: LCP <2.5s, CLS <0.1
|
||||
- Sem dependencias externas pesadas (max framer-motion ou CSS puro)
|
||||
- Acessibilidade basica (alt text, contraste, focus states)
|
||||
3. Incluir comentarios no HTML com seccoes claras
|
||||
|
||||
### Passo 4 — Preview
|
||||
|
||||
1. Abrir `index.html` no browser local: `xdg-open /tmp/cinematic-site/output/index.html`
|
||||
2. Tirar screenshot via `mcp__chrome-devtools__take_screenshot`
|
||||
3. Mostrar comparacao ao utilizador:
|
||||
- Site original (URL)
|
||||
- Novo site (screenshot)
|
||||
4. Pedir aprovacao antes de qualquer proximo passo
|
||||
5. Se aprovado, sugerir opcoes:
|
||||
- Copiar para pasta de projecto
|
||||
- Ajustar cores/seccoes
|
||||
- Exportar para Vercel/Netlify (manual)
|
||||
|
||||
---
|
||||
|
||||
## Regras
|
||||
|
||||
- **Nunca deploy automatico** — apenas preview local
|
||||
- **Nunca inventar conteudo** — usar texto real do site original
|
||||
- **Sempre referenciar design.json** para standards visuais
|
||||
- **Output em /tmp/cinematic-site/** — nunca em pastas de projecto sem aprovacao
|
||||
- **README.md incluido** com instrucoes de deploy manual
|
||||
|
||||
---
|
||||
|
||||
## Healing Log
|
||||
|
||||
```jsonl
|
||||
{"date":"","issue":"","fix":"","source":"user|auto"}
|
||||
```
|
||||
@@ -0,0 +1,120 @@
|
||||
---
|
||||
name: clone-style
|
||||
description: Clona o estilo visual de um site ou apresentação extraindo design tokens (cores, tipografia, espaçamento, raios, sombras) e gerando JSON compatível com Stitch, design-engine e pptx-generator. Usar quando "clonar estilo", "clone style", "extrair design", "copiar visual", "tokens design", "clone web", "clone slides", "design tokens".
|
||||
layer: wiki
|
||||
---
|
||||
|
||||
# /clone-style — Extrair Design Tokens de Sites e Slides
|
||||
|
||||
## Princípio fundamental
|
||||
|
||||
**Não tentes recriar visualmente — extrai o sistema.** Captura os tokens (cores, fontes, espaçamentos, raios) e alimenta uma ferramenta generativa. A fidelidade vem do sistema, não da imitação pixel a pixel.
|
||||
|
||||
## Modos
|
||||
|
||||
| Comando | Fonte | Output |
|
||||
|---|---|---|
|
||||
| `/clone-style web <url>` | Site live (browser real, CSS computado) | `tokens.json` + screenshots componentes |
|
||||
| `/clone-style slides <pptx_path>` | Ficheiro PPTX local | `tokens.json` (theme1.xml + slideMasters) |
|
||||
| `/clone-style apply <tokens.json>` | Design tokens já extraídos | Aplicação no Stitch / design-engine / pptx-generator |
|
||||
|
||||
---
|
||||
|
||||
## Modo 1 — Web
|
||||
|
||||
### Workflow
|
||||
|
||||
1. **Abrir URL no Chrome real** via `mcp__claude-in-chrome__navigate` (preferido — captura sessões logged-in se necessário) ou `mcp__chrome-devtools__navigate_page`.
|
||||
|
||||
2. **Aguardar render completo** (`wait_for` "load" + 2s extra para JS).
|
||||
|
||||
3. **Injectar script de extracção** via `mcp__claude-in-chrome__javascript_tool` ou `mcp__chrome-devtools__evaluate_script`. O script está em `references/extract-web-tokens.js`. Cola-o dentro do tool call.
|
||||
|
||||
4. **O script devolve JSON estruturado** com:
|
||||
- `colors`: paleta deduplicada + ranking por frequência (top 12)
|
||||
- `fonts`: famílias únicas + tamanhos + pesos + line-heights
|
||||
- `spacing`: gaps/paddings/margins agrupados (encontra grid base 4px/8px)
|
||||
- `borderRadius`: pequeno/médio/grande/full (clusters)
|
||||
- `shadows`: box-shadows únicas
|
||||
- `componentes`: HTML+CSS de buttons, cards, nav, hero (capturados como referência)
|
||||
|
||||
5. **Capturar screenshots** dos componentes detectados via `mcp__chrome-devtools__take_screenshot` ou `mcp__claude-in-chrome__computer` (full + por componente).
|
||||
|
||||
6. **Mapear para Stitch** (ver secção "Mapeamento Stitch" abaixo) — cores → primary seed, fonte mais usada → enum match, raio dominante → ROUND_*.
|
||||
|
||||
7. **Guardar** em `~/.claude-work/clone-style/<dominio>-<timestamp>/tokens.json` + `screenshots/`.
|
||||
|
||||
### Comando exemplo
|
||||
|
||||
```
|
||||
/clone-style web https://linear.app
|
||||
```
|
||||
|
||||
Output esperado:
|
||||
- `~/.claude-work/clone-style/linear-app-20260407/tokens.json`
|
||||
- `~/.claude-work/clone-style/linear-app-20260407/screenshots/full.png`
|
||||
- `~/.claude-work/clone-style/linear-app-20260407/screenshots/hero.png`
|
||||
- `~/.claude-work/clone-style/linear-app-20260407/screenshots/buttons.png`
|
||||
- Resumo no terminal: paleta + fontes + sugestão de aplicação
|
||||
|
||||
---
|
||||
|
||||
## Modo 2 — Slides (PPTX)
|
||||
|
||||
PPTX é um ZIP de XML. Toda a informação de tema está em `ppt/theme/theme1.xml` e `ppt/slideMasters/slideMaster1.xml`.
|
||||
|
||||
### Workflow
|
||||
|
||||
1. **Verificar input** existe e é PPTX válido (`unzip -l <file>` para listar entradas).
|
||||
|
||||
2. **Extrair em tmp**: `unzip -o <file> -d /tmp/clone-style-pptx-<ts>/`.
|
||||
|
||||
3. **Parsear `theme1.xml`** (Python ou xmllint):
|
||||
```python
|
||||
import xml.etree.ElementTree as ET
|
||||
ns = {'a': 'http://schemas.openxmlformats.org/drawingml/2006/main'}
|
||||
tree = ET.parse('ppt/theme/theme1.xml')
|
||||
root = tree.getroot()
|
||||
|
||||
# Cores tema (accent1-6, dark1, dark2, light1, light2, hyperlink, followedHyperlink)
|
||||
colors = {}
|
||||
for child in root.iter('{http://schemas.openxmlformats.org/drawingml/2006/main}clrScheme'):
|
||||
for color_node in child:
|
||||
name = color_node.tag.split('}')[1]
|
||||
srgb = color_node.find('a:srgbClr', ns)
|
||||
sysclr = color_node.find('a:sysClr', ns)
|
||||
if srgb is not None:
|
||||
colors[name] = '#' + srgb.get('val')
|
||||
elif sysclr is not None:
|
||||
colors[name] = '#' + sysclr.get('lastClr', '000000')
|
||||
|
||||
# Fontes (major = headlines, minor = body)
|
||||
fonts = {}
|
||||
for fs in root.iter('{http://schemas.openxmlformats.org/drawingml/2006/main}fontScheme'):
|
||||
major = fs.find('a:majorFont/a:latin', ns)
|
||||
minor = fs.find('a:minorFont/a:latin', ns)
|
||||
if major is not None: fonts['headline'] = major.get('typeface')
|
||||
if minor is not None: fonts['body'] = minor.get('typeface')
|
||||
```
|
||||
|
||||
4. **Parsear `slideMaster1.xml`** para layouts dominantes (background, posições, sizes default).
|
||||
|
||||
5. **Output `tokens.json`** no mesmo formato do Modo 1 (para que `apply` seja unificado).
|
||||
|
||||
### Comando exemplo
|
||||
|
||||
```
|
||||
/clone-style slides /home/ealmeida/Downloads/template-cliente.pptx
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Modo 3 — Apply
|
||||
|
||||
Recebe `tokens.json` e aplica numa das 3 ferramentas:
|
||||
|
||||
### A) Stitch (web/UI)
|
||||
|
||||
**Limitação importante:** Stitch só aceita um conjunto restrito de tokens (ver schema `mcp__stitch__create_design_system`):
|
||||
- 1 `customColor` (seed) + opcionais `overridePrimaryColor`/`overrideSecondaryColor`/`overrideTertiaryColor`/`overrideNeutralColor`
|
||||
-
|
||||
@@ -0,0 +1,133 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
extract-pptx-theme.py — extrai design tokens de um ficheiro PPTX
|
||||
|
||||
Uso:
|
||||
python3 extract-pptx-theme.py <caminho.pptx> [--output tokens.json]
|
||||
|
||||
Devolve JSON no mesmo formato do extract-web-tokens.js para que /clone-style apply
|
||||
seja unificado entre os 2 modos.
|
||||
"""
|
||||
import sys
|
||||
import json
|
||||
import zipfile
|
||||
import xml.etree.ElementTree as ET
|
||||
from pathlib import Path
|
||||
from datetime import datetime, timezone
|
||||
|
||||
NS = {'a': 'http://schemas.openxmlformats.org/drawingml/2006/main'}
|
||||
|
||||
|
||||
def extract_theme(pptx_path: Path) -> dict:
|
||||
if not pptx_path.exists():
|
||||
raise FileNotFoundError(f"Não encontrado: {pptx_path}")
|
||||
|
||||
with zipfile.ZipFile(pptx_path) as z:
|
||||
# Listar themes (pode haver múltiplos; usar o primeiro)
|
||||
theme_files = sorted([n for n in z.namelist() if n.startswith('ppt/theme/theme') and n.endswith('.xml')])
|
||||
if not theme_files:
|
||||
raise ValueError("PPTX sem theme — formato inválido ou corrompido")
|
||||
|
||||
theme_xml = z.read(theme_files[0])
|
||||
root = ET.fromstring(theme_xml)
|
||||
|
||||
# Extrair cores do clrScheme
|
||||
colors = {}
|
||||
for clr_scheme in root.iter('{http://schemas.openxmlformats.org/drawingml/2006/main}clrScheme'):
|
||||
for color_node in clr_scheme:
|
||||
name = color_node.tag.split('}')[1] # ex: 'accent1', 'dk1', 'lt1'
|
||||
srgb = color_node.find('a:srgbClr', NS)
|
||||
sysclr = color_node.find('a:sysClr', NS)
|
||||
if srgb is not None:
|
||||
colors[name] = '#' + srgb.get('val')
|
||||
elif sysclr is not None:
|
||||
# sysClr usa o lastClr como fallback (cor resolvida)
|
||||
colors[name] = '#' + sysclr.get('lastClr', '000000')
|
||||
|
||||
# Extrair fontes do fontScheme
|
||||
fonts = {'headline': None, 'body': None}
|
||||
for fs in root.iter('{http://schemas.openxmlformats.org/drawingml/2006/main}fontScheme'):
|
||||
major = fs.find('a:majorFont/a:latin', NS)
|
||||
minor = fs.find('a:minorFont/a:latin', NS)
|
||||
if major is not None:
|
||||
fonts['headline'] = major.get('typeface')
|
||||
if minor is not None:
|
||||
fonts['body'] = minor.get('typeface')
|
||||
|
||||
# Mapear cores PPTX → estrutura unificada
|
||||
accent_keys = ['accent1', 'accent2', 'accent3', 'accent4', 'accent5', 'accent6']
|
||||
accents = [colors[k] for k in accent_keys if k in colors]
|
||||
|
||||
primary = colors.get('accent1') or accents[0] if accents else '#000000'
|
||||
secondary = colors.get('accent2')
|
||||
tertiary = colors.get('accent3')
|
||||
neutral = colors.get('lt1') or colors.get('dk1') or '#ffffff'
|
||||
background = colors.get('lt1') or colors.get('bg1') or '#ffffff'
|
||||
|
||||
is_dark = colors.get('lt1', '#ffffff').lstrip('#').upper() != 'FFFFFF'
|
||||
|
||||
return {
|
||||
'url': str(pptx_path),
|
||||
'title': pptx_path.stem,
|
||||
'source': 'pptx',
|
||||
'timestamp': datetime.now(timezone.utc).isoformat(),
|
||||
'colors': {
|
||||
'top': [{'value': v, 'count': 1} for v in accents],
|
||||
'backgrounds': [{'value': background, 'count': 1}],
|
||||
'dominant': primary,
|
||||
'raw_scheme': colors,
|
||||
},
|
||||
'fonts': {
|
||||
'families': [
|
||||
{'value': fonts['headline'], 'count': 1, 'role': 'headline'},
|
||||
{'value': fonts['body'], 'count': 1, 'role': 'body'},
|
||||
],
|
||||
'sizes': [],
|
||||
'weights': [],
|
||||
'lineHeights': [],
|
||||
},
|
||||
'borderRadius': [],
|
||||
'shadows': [],
|
||||
'spacing': {'gridBaseGuess': 8, 'top': []},
|
||||
'components': {},
|
||||
'meta': {
|
||||
'colorMode': 'DARK' if is_dark else 'LIGHT',
|
||||
'theme_file': theme_files[0],
|
||||
'accent_count': len(accents),
|
||||
},
|
||||
'mapping_hint': {
|
||||
'stitch_customColor': primary,
|
||||
'stitch_overrideSecondary': secondary,
|
||||
'stitch_overrideTertiary': tertiary,
|
||||
'stitch_overrideNeutral': neutral,
|
||||
'note': 'PPTX só fornece cores e fontes — borderRadius/shadows/spacing têm de ser definidos manualmente em designMd',
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 2:
|
||||
print(__doc__, file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
pptx = Path(sys.argv[1]).expanduser().resolve()
|
||||
|
||||
output_path = None
|
||||
if '--output' in sys.argv:
|
||||
idx = sys.argv.index('--output')
|
||||
if idx + 1 < len(sys.argv):
|
||||
output_path = Path(sys.argv[idx + 1]).expanduser().resolve()
|
||||
|
||||
tokens = extract_theme(pptx)
|
||||
js = json.dumps(tokens, indent=2, ensure_ascii=False)
|
||||
|
||||
if output_path:
|
||||
output_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
output_path.write_text(js, encoding='utf-8')
|
||||
print(f"✅ Tokens guardados em {output_path}", file=sys.stderr)
|
||||
else:
|
||||
print(js)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,122 @@
|
||||
// extract-web-tokens.js
|
||||
// Injectar via mcp__claude-in-chrome__javascript_tool ou mcp__chrome-devtools__evaluate_script
|
||||
// Devolve JSON com cores, fontes, espaçamentos, raios, sombras e amostras de componentes.
|
||||
// Funciona em qualquer site (incluindo JS-rendered) porque usa getComputedStyle().
|
||||
|
||||
(() => {
|
||||
const all = document.querySelectorAll('*');
|
||||
const colorCounts = {};
|
||||
const fontFamilies = {};
|
||||
const fontSizes = {};
|
||||
const fontWeights = {};
|
||||
const lineHeights = {};
|
||||
const radii = {};
|
||||
const shadows = {};
|
||||
const spacings = {};
|
||||
const bgColors = {};
|
||||
|
||||
const norm = (v) => (v || '').trim();
|
||||
const inc = (obj, k) => { if (!k || k === 'none' || k === '0px') return; obj[k] = (obj[k] || 0) + 1; };
|
||||
|
||||
// Helper: rgb(a) → hex (ignora transparente)
|
||||
const toHex = (rgb) => {
|
||||
if (!rgb || rgb === 'transparent' || rgb === 'rgba(0, 0, 0, 0)') return null;
|
||||
const m = rgb.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/);
|
||||
if (!m) return null;
|
||||
const a = m[4] !== undefined ? parseFloat(m[4]) : 1;
|
||||
if (a < 0.1) return null;
|
||||
const h = (n) => parseInt(n).toString(16).padStart(2, '0');
|
||||
return '#' + h(m[1]) + h(m[2]) + h(m[3]);
|
||||
};
|
||||
|
||||
for (const el of all) {
|
||||
if (!(el instanceof Element)) continue;
|
||||
const cs = getComputedStyle(el);
|
||||
|
||||
// Cores
|
||||
inc(colorCounts, toHex(cs.color));
|
||||
const bg = toHex(cs.backgroundColor);
|
||||
if (bg) {
|
||||
inc(bgColors, bg);
|
||||
inc(colorCounts, bg);
|
||||
}
|
||||
inc(colorCounts, toHex(cs.borderColor));
|
||||
|
||||
// Fontes
|
||||
inc(fontFamilies, norm(cs.fontFamily));
|
||||
inc(fontSizes, norm(cs.fontSize));
|
||||
inc(fontWeights, norm(cs.fontWeight));
|
||||
inc(lineHeights, norm(cs.lineHeight));
|
||||
|
||||
// Raios
|
||||
inc(radii, norm(cs.borderRadius));
|
||||
|
||||
// Sombras
|
||||
if (cs.boxShadow && cs.boxShadow !== 'none') inc(shadows, cs.boxShadow);
|
||||
|
||||
// Espaçamentos (paddings + margins + gap)
|
||||
['paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft', 'marginTop', 'marginRight', 'marginBottom', 'marginLeft', 'gap', 'rowGap', 'columnGap'].forEach((p) => {
|
||||
inc(spacings, norm(cs[p]));
|
||||
});
|
||||
}
|
||||
|
||||
// Top N por frequência
|
||||
const topN = (obj, n) => Object.entries(obj).sort((a, b) => b[1] - a[1]).slice(0, n).map(([k, v]) => ({ value: k, count: v }));
|
||||
|
||||
// Detectar grid base (espaçamento mais comum)
|
||||
const numericSpacings = Object.entries(spacings)
|
||||
.map(([k, v]) => [parseFloat(k), v])
|
||||
.filter(([n]) => !isNaN(n) && n > 0 && n < 200)
|
||||
.sort((a, b) => b[1] - a[1]);
|
||||
const gridBase = numericSpacings[0]?.[0] || 8;
|
||||
|
||||
// Capturar samples HTML de componentes-chave (pelo selector)
|
||||
const sample = (sel) => {
|
||||
const el = document.querySelector(sel);
|
||||
if (!el) return null;
|
||||
return {
|
||||
html: el.outerHTML.substring(0, 800),
|
||||
computed: {
|
||||
bg: toHex(getComputedStyle(el).backgroundColor),
|
||||
color: toHex(getComputedStyle(el).color),
|
||||
radius: getComputedStyle(el).borderRadius,
|
||||
padding: getComputedStyle(el).padding,
|
||||
font: getComputedStyle(el).fontFamily,
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
url: location.href,
|
||||
title: document.title,
|
||||
timestamp: new Date().toISOString(),
|
||||
colors: {
|
||||
top: topN(colorCounts, 12),
|
||||
backgrounds: topN(bgColors, 6),
|
||||
dominant: topN(colorCounts, 1)[0]?.value || null,
|
||||
},
|
||||
fonts: {
|
||||
families: topN(fontFamilies, 5),
|
||||
sizes: topN(fontSizes, 8),
|
||||
weights: topN(fontWeights, 6),
|
||||
lineHeights: topN(lineHeights, 6),
|
||||
},
|
||||
borderRadius: topN(radii, 6),
|
||||
shadows: topN(shadows, 5),
|
||||
spacing: {
|
||||
gridBaseGuess: gridBase,
|
||||
top: topN(spacings, 12),
|
||||
},
|
||||
components: {
|
||||
button: sample('button, .btn, [class*="button" i]'),
|
||||
card: sample('.card, [class*="card" i]'),
|
||||
nav: sample('nav, header, [class*="nav" i]'),
|
||||
hero: sample('main > section:first-child, .hero, [class*="hero" i]'),
|
||||
},
|
||||
meta: {
|
||||
colorMode: getComputedStyle(document.body).backgroundColor.includes('255') ? 'LIGHT' : 'DARK',
|
||||
lang: document.documentElement.lang || 'unknown',
|
||||
viewport: document.querySelector('meta[name=viewport]')?.content || null,
|
||||
}
|
||||
};
|
||||
})();
|
||||
@@ -0,0 +1,67 @@
|
||||
---
|
||||
name: design-b2b
|
||||
description: >
|
||||
Design system para serviços B2B — agências, consultoria, SaaS, PMEs portuguesas.
|
||||
Propostas visuais, landing pages, apresentações e materiais para decisores PT.
|
||||
Usar quando: proposta comercial, landing page serviço B2B, apresentação cliente,
|
||||
one-pager, ou qualquer material visual para audiência empresarial portuguesa.
|
||||
layer: wiki
|
||||
---
|
||||
|
||||
# /design-b2b — Design System Serviços B2B
|
||||
|
||||
## Paleta
|
||||
|
||||
```css
|
||||
--primary: #1e3a5f; /* Azul institucional — confiança, autoridade */
|
||||
--accent: #f97316; /* Laranja acção — CTAs, destaques */
|
||||
--neutral: #f8fafc; /* Fundo profissional */
|
||||
--text: #1e293b; /* Texto principal */
|
||||
--muted: #64748b; /* Texto secundário, legendas */
|
||||
--border: #e2e8f0; /* Divisores subtis */
|
||||
```
|
||||
|
||||
## Estrutura proposta comercial
|
||||
|
||||
### One-pager (1 A4 ou landing page equivalente)
|
||||
1. **Header:** Logo cliente + logo Descomplicar + título proposta
|
||||
2. **Problema:** 2-3 bullets do problema actual do cliente
|
||||
3. **Solução:** O que entregamos (concreto, não vago)
|
||||
4. **Resultados:** Métricas esperadas (%, EUR, tempo)
|
||||
5. **Investimento:** Preço claro, sem asteriscos escondidos
|
||||
6. **Próximo passo:** CTA único — "Agendar Reunião" ou "Aceitar Proposta"
|
||||
|
||||
### Landing page serviço B2B
|
||||
1. Headline: benefício principal (não feature)
|
||||
2. Sub-headline: para quem é + resultado esperado
|
||||
3. Prova social: 3 logos de clientes ou 1 case study
|
||||
4. Serviços: 3-5 cards com ícone + nome + 1 linha
|
||||
5. Processo: 3-4 passos (simples e claro)
|
||||
6. CTA: formulário simples (nome, email, empresa, mensagem)
|
||||
|
||||
## Tom e linguagem B2B PT
|
||||
|
||||
- **Usar:** "optimizar", "aumentar eficiência", "reduzir custos"
|
||||
- **Evitar:** "disruptivo", "revolucionário", "próximo nível"
|
||||
- **Tratamento:** "Você" (neutro) ou "A sua empresa" — nunca "tu" em contexto formal
|
||||
- **Números:** sempre com fonte (ex: "30% redução de custos — caso Empresa X")
|
||||
|
||||
## Anti-slop checklist B2B
|
||||
|
||||
- [ ] Zero jargão sem explicação
|
||||
- [ ] Preços ou "Solicitar orçamento" — nunca ambiguidade
|
||||
- [ ] Casos reais, não hipotéticos
|
||||
- [ ] Mobile: decisores usam telemóvel para primeiro contacto
|
||||
- [ ] Social proof: logo real, não ilustração
|
||||
|
||||
## Referências visuais
|
||||
|
||||
Ver `~/.claude/design/referencias-visuais/servicos-b2b/`
|
||||
|
||||
---
|
||||
|
||||
## Healing Log
|
||||
|
||||
```jsonl
|
||||
{"date":"","issue":"","fix":"","source":"user|auto"}
|
||||
```
|
||||
@@ -0,0 +1,65 @@
|
||||
---
|
||||
name: design-ecommerce
|
||||
description: >
|
||||
Design system para e-commerce — lojas WooCommerce, páginas produto, checkout PT.
|
||||
Optimização conversão, layouts loja, UX checkout e elementos de confiança.
|
||||
Usar quando: criar ou optimizar loja WooCommerce, página produto, carrinho,
|
||||
checkout, ou qualquer elemento visual de e-commerce para mercado português.
|
||||
layer: wiki
|
||||
---
|
||||
|
||||
# /design-ecommerce — Design System E-commerce
|
||||
|
||||
## Paleta base (adaptar à marca do cliente)
|
||||
|
||||
```css
|
||||
--cta: #dc2626; /* Vermelho urgência — "Comprar Agora" */
|
||||
--trust: #16a34a; /* Verde confiança — "Pagamento Seguro" */
|
||||
--price: #1e3a5f; /* Azul preço destacado */
|
||||
--sale: #f59e0b; /* Âmbar promoção */
|
||||
--neutral: #ffffff;
|
||||
--text: #111827;
|
||||
```
|
||||
|
||||
## Elementos conversão obrigatórios
|
||||
|
||||
### Página produto
|
||||
1. Imagens: mínimo 4 ângulos, zoom, vídeo se possível
|
||||
2. Preço: destacado, desconto visível, preço original riscado
|
||||
3. Stock: urgência ("Últimas 3 unidades")
|
||||
4. CTA: "Adicionar ao Carrinho" (vermelho, proeminente)
|
||||
5. Confiança: selos Visa/MB/MBWay + devolução 30 dias
|
||||
6. Avaliações: estrelas + número (social proof)
|
||||
7. "Também pode gostar" + "Compraram juntos"
|
||||
|
||||
### Checkout PT
|
||||
- Referência Multibanco visível
|
||||
- MB Way como opção principal
|
||||
- Campo NIF opcional (B2B)
|
||||
- Morada: formato PT (Rua, nº, andar, código postal, localidade)
|
||||
|
||||
### Elementos de confiança PT
|
||||
- Selos: MBWay, Visa, Mastercard, PayPal
|
||||
- "Envio para Portugal Continental em 24-48h"
|
||||
- "Devolução gratuita em 30 dias"
|
||||
- "Suporte em português"
|
||||
|
||||
## Anti-slop checklist e-commerce
|
||||
|
||||
- [ ] Preços em EUR (não USD)
|
||||
- [ ] CTAs em PT-PT: "Comprar" não "Buy", "Carrinho" não "Cart"
|
||||
- [ ] Mobile: checkout testado em 375px (maioria compra no telemóvel)
|
||||
- [ ] Tempo de carregamento: imagens optimizadas <100KB
|
||||
- [ ] Trust badges visíveis acima do fold
|
||||
|
||||
## Referências visuais
|
||||
|
||||
Ver `~/.claude/design/referencias-visuais/ecommerce/`
|
||||
|
||||
---
|
||||
|
||||
## Healing Log
|
||||
|
||||
```jsonl
|
||||
{"date":"","issue":"","fix":"","source":"user|auto"}
|
||||
```
|
||||
@@ -0,0 +1,63 @@
|
||||
---
|
||||
name: design-saude
|
||||
description: >
|
||||
Design system para sector saúde — clínicas, KiviCare, consultórios médicos.
|
||||
Paleta, tipografia, CTAs e layouts optimizados para contexto clínico PT.
|
||||
Usar quando: criar landing page de clínica, página de serviços médicos,
|
||||
agendamento online, ou qualquer material visual para clientes saúde.
|
||||
layer: wiki
|
||||
---
|
||||
|
||||
# /design-saude — Design System Saúde
|
||||
|
||||
## Paleta
|
||||
|
||||
```css
|
||||
--primary: #0ea5e9; /* Azul confiança médica */
|
||||
--secondary: #10b981; /* Verde saúde/cura */
|
||||
--neutral: #f8fafc; /* Fundo limpo e asséptico */
|
||||
--text: #1e293b; /* Texto principal */
|
||||
--accent: #f59e0b; /* CTA urgência (marcar consulta) */
|
||||
--danger: #ef4444; /* Alertas, urgências */
|
||||
```
|
||||
|
||||
## Tipografia
|
||||
|
||||
- **Títulos:** Inter SemiBold — transmite profissionalismo sem frieza
|
||||
- **Corpo:** Inter Regular 16px, line-height 1.7 — legibilidade para público 40+
|
||||
- **Evitar:** fontes decorativas, cursivas, serifas antiquadas
|
||||
|
||||
## Layouts obrigatórios
|
||||
|
||||
### Landing page clínica
|
||||
1. Hero: foto médico real + headline "Cuidamos de si" + CTA "Marcar Consulta"
|
||||
2. Serviços: cards com ícone + nome + preço (se disponível)
|
||||
3. Equipa: fotos reais + credenciais
|
||||
4. Depoimentos: com nome e tratamento (anonimizado se necessário)
|
||||
5. Localização + horários + contacto
|
||||
6. CTA final: WhatsApp ou formulário
|
||||
|
||||
### CTAs saúde
|
||||
- Principal: "Marcar Consulta" (verde, proeminente)
|
||||
- Secundário: "Saber Mais" ou "Ver Serviços"
|
||||
- Urgência: "Consulta Hoje" (âmbar)
|
||||
|
||||
## Anti-slop checklist saúde
|
||||
|
||||
- [ ] Fotos de pessoas reais (não stock de médicos brancos genéricos)
|
||||
- [ ] RGPD: sem dados de pacientes visíveis em mockups
|
||||
- [ ] Cores acessíveis: contraste WCAG AA mínimo
|
||||
- [ ] Mobile: formulário agendamento testado em 375px
|
||||
- [ ] PT-PT: "consulta" não "appointment", "médico" não "doctor"
|
||||
|
||||
## Referências visuais
|
||||
|
||||
Ver `~/.claude/design/referencias-visuais/saude/`
|
||||
|
||||
---
|
||||
|
||||
## Healing Log
|
||||
|
||||
```jsonl
|
||||
{"date":"","issue":"","fix":"","source":"user|auto"}
|
||||
```
|
||||
@@ -0,0 +1,61 @@
|
||||
---
|
||||
name: design-solar
|
||||
description: >
|
||||
Design system para sector solar/fotovoltaico — SolarFV, instaladores, B2B energia.
|
||||
Paleta, calculadoras, propostas visuais e layouts para sector energias renováveis PT.
|
||||
Usar quando: landing page solar, proposta instalação FV, calculadora poupança,
|
||||
ou material visual para clientes energia solar.
|
||||
layer: wiki
|
||||
---
|
||||
|
||||
# /design-solar — Design System Solar/FV
|
||||
|
||||
## Paleta
|
||||
|
||||
```css
|
||||
--primary: #f59e0b; /* Amarelo solar — energia, optimismo */
|
||||
--secondary: #1e3a5f; /* Azul escuro — confiança, profissionalismo B2B */
|
||||
--green: #16a34a; /* Verde sustentabilidade */
|
||||
--neutral: #f9fafb; /* Fundo limpo */
|
||||
--text: #111827; /* Texto principal */
|
||||
```
|
||||
|
||||
## Elementos distintivos sector solar
|
||||
|
||||
### Calculadora de poupança (elemento central)
|
||||
- Input: consumo mensal kWh + factura actual
|
||||
- Output: poupança anual estimada + payback em anos
|
||||
- Visual: comparação antes/depois com gráfico simples
|
||||
|
||||
### Proposta instalação
|
||||
1. Sumário executivo (1 página): consumo actual → produção estimada → ROI
|
||||
2. Especificações técnicas: painéis, inversor, capacidade
|
||||
3. Financiamento: opções (compra, leasing, PPA)
|
||||
4. Garantias e certificações
|
||||
5. CTA: "Solicitar Visita Técnica"
|
||||
|
||||
## Tipografia
|
||||
|
||||
- **Títulos:** Poppins Bold — moderno, energético
|
||||
- **Dados/métricas:** Inter Mono — leiturabilidade para números
|
||||
- **Corpo:** Inter Regular
|
||||
|
||||
## Anti-slop checklist solar
|
||||
|
||||
- [ ] Números reais de produção (não inventar kWh)
|
||||
- [ ] Certificações visíveis (DGEG, SCE)
|
||||
- [ ] Mobile: calculadora funcional em 375px
|
||||
- [ ] B2B: tom técnico e sóbrio (não "salve o planeta")
|
||||
- [ ] PT: "fotovoltaico" não "fotovoltaica" (painel fotovoltaico)
|
||||
|
||||
## Referências visuais
|
||||
|
||||
Ver `~/.claude/design/referencias-visuais/solar/`
|
||||
|
||||
---
|
||||
|
||||
## Healing Log
|
||||
|
||||
```jsonl
|
||||
{"date":"","issue":"","fix":"","source":"user|auto"}
|
||||
```
|
||||
@@ -0,0 +1,147 @@
|
||||
---
|
||||
name: design
|
||||
description: Motor de design profissional multi-marca. Gera apresentações, infográficos, logos, social media, web pages e identidade visual.
|
||||
layer: wiki
|
||||
---
|
||||
|
||||
# /design - Motor de Design Profissional
|
||||
|
||||
Ponto de entrada unificado para o sistema de design multi-marca. Routing automatico para o motor adequado.
|
||||
|
||||
## Contexto NotebookLM
|
||||
|
||||
ANTES de executar, consultar notebooks para contexto especializado:
|
||||
|
||||
| Notebook | ID | Consultar quando |
|
||||
|----------|-----|-----------------|
|
||||
| Tipografia e Cor para Web | f97a0d2b | Sempre |
|
||||
| UI/UX Design | 081ca512 | Para decisões de interface |
|
||||
| Design Profissional AItomatizado | b568b13b-0eed-48c9-b513-5c5b7ec0b102 | Sempre |
|
||||
|
||||
```
|
||||
mcp__notebooklm__notebook_query({
|
||||
notebook_id: "f97a0d2b-a5b3-4640-b941-3cbb184b1b81",
|
||||
query: "<adaptar ao contexto do pedido do utilizador>"
|
||||
})
|
||||
|
||||
mcp__notebooklm__notebook_query({
|
||||
notebook_id: "081ca512-8279-4850-b2b9-dff090267482",
|
||||
query: "<adaptar ao contexto de interface/UX do pedido>"
|
||||
})
|
||||
|
||||
mcp__notebooklm__notebook_query({
|
||||
notebook_id: "b568b13b-0eed-48c9-b513-5c5b7ec0b102",
|
||||
query: "<adaptar ao contexto de design profissional e automação>"
|
||||
})
|
||||
```
|
||||
|
||||
Integrar insights do NotebookLM nas recomendações e decisões.
|
||||
|
||||
---
|
||||
|
||||
## Comandos
|
||||
|
||||
| Comando | Output | Motor |
|
||||
|---------|--------|-------|
|
||||
| `/design [descricao]` | Routing automatico | Auto |
|
||||
| `/design presentation [tema]` | Apresentacao PPTX/PDF | Presenton |
|
||||
| `/design infographic [tema]` | Infografico PNG/PDF | design-engine (Fibo/Gemini) |
|
||||
| `/design social [plataforma] [tema]` | Post redes sociais | design-engine |
|
||||
| `/design web [descricao]` | Landing page / web component | **Stitch (motor principal)** |
|
||||
| `/design logo [nome]` | Logo SVG + variacoes | design-engine + Fibo |
|
||||
| `/design brand [empresa]` | Identidade visual completa | Stitch + design-engine |
|
||||
| `/design from-reference [url]` | Analisa e recria adaptado | Auto |
|
||||
|
||||
## Parametros Opcionais
|
||||
|
||||
| Parametro | Descricao | Exemplo |
|
||||
|-----------|-----------|---------|
|
||||
| `--brand [nome]` | Aplicar identidade de marca | `--brand descomplicar` |
|
||||
| `--tone [tom]` | Tom da apresentacao | `--tone sales_pitch` |
|
||||
| `--format [fmt]` | Formato de exportacao | `--format pdf` |
|
||||
| `--variations [n]` | Numero de variacoes | `--variations 5` |
|
||||
|
||||
## Workflow
|
||||
|
||||
```
|
||||
1. PARSE comando e parametros
|
||||
2. IDENTIFICAR tipo de output
|
||||
- "presentation" / "slides" / "proposta" -> Presenton
|
||||
- "infographic" / "poster" / "flyer" -> design-engine (Fibo/Gemini)
|
||||
- "social" / "instagram" / "linkedin" -> design-engine (com dimensões)
|
||||
- "web" / "landing" / "page" / "ui" -> Stitch
|
||||
- "logo" / "icone" / "marca" -> design-engine + Fibo
|
||||
- "brand" / "identidade" -> Stitch (web) + design-engine (assets)
|
||||
- "from-reference" -> Researcher primeiro
|
||||
3. SE --brand especificado:
|
||||
- Carregar brand pack via design-engine MCP: brand_load(nome)
|
||||
- Aplicar cores, fontes e logo a todos os outputs
|
||||
4. DELEGAR a design-lead agent (orquestrador)
|
||||
5. APRESENTAR resultados ao utilizador
|
||||
```
|
||||
|
||||
## Exemplos de Uso
|
||||
|
||||
### Apresentacao com marca
|
||||
```
|
||||
/design presentation "Proposta de servicos web para empresa X" --brand descomplicar
|
||||
```
|
||||
Resultado: PPTX profissional via Presenton com cores dourado/preto, logo Descomplicar, fonte Nexa.
|
||||
|
||||
### Post Instagram
|
||||
```
|
||||
/design social instagram "Promocao Black Friday -30%"
|
||||
```
|
||||
Resultado: Imagem 1080x1080 gerada via design-engine (Fibo/Gemini) com texto, cores e layout profissional.
|
||||
|
||||
### Landing page
|
||||
```
|
||||
/design web "Landing page para agencia de marketing digital" --brand descomplicar
|
||||
```
|
||||
Resultado: HTML/CSS via Stitch com Design DNA da marca.
|
||||
|
||||
### Infografico
|
||||
```
|
||||
/design infographic "Top 10 tendencias AI 2026"
|
||||
```
|
||||
Resultado: PNG/PDF vertical gerado via design-engine com icones, dados e hierarquia visual.
|
||||
|
||||
### Identidade visual completa
|
||||
```
|
||||
/design brand "Nova Empresa Tech"
|
||||
```
|
||||
Resultado: Logo + paleta + tipografia + templates social + template apresentacao.
|
||||
|
||||
### A partir de referencia
|
||||
```
|
||||
/design from-reference https://figma.com/file/abc123
|
||||
```
|
||||
Resultado: Analisa design Figma, extrai estilo, recria adaptado.
|
||||
|
||||
## MCPs de Design (4)
|
||||
|
||||
| MCP | Funcao |
|
||||
|-----|--------|
|
||||
| **design-engine** | Imagens AI (Fibo/Gemini) + brand packs + rembg + composição |
|
||||
| **presenton** | Apresentacoes AI (slide.descomplicar.pt) |
|
||||
| **stitch** | Web design AI text→UI (Google Labs) — motor principal para web/ui/landing |
|
||||
| **figma** | Analise referencias (read-only) |
|
||||
|
||||
> **Penpot suspenso 07-04-2026 sessão 5** — substituído por Stitch (text→UI generation). MCP penpot removido. Se Stitch for descontinuado, reavaliar.
|
||||
|
||||
## Brand Packs Disponiveis
|
||||
|
||||
Verificar com: `brand_list()` via design-engine MCP.
|
||||
|
||||
Brand packs em: `/media/ealmeida/Dados/Hub/04-Recursos/Design/brands/`
|
||||
|
||||
Formato: `{nome}.json` com cores, fontes, logos, voz, estilo.
|
||||
|
||||
## Dimensoes Social Media
|
||||
|
||||
| Plataforma | Formato | Dimensoes |
|
||||
|------------|---------|-----------|
|
||||
| Instagram Post | 1:1 | 1080x1080 |
|
||||
| Instagram Story | 9:16 | 1080x1920 |
|
||||
| LinkedIn Post | ~2:1 | 1200x628 |
|
||||
| YouTube Thumbnail | 1
|
||||
@@ -0,0 +1,289 @@
|
||||
# Referência: Propostas Premium — Design de Capas e Páginas Visuais
|
||||
|
||||
Guia prático para criar páginas visuais de impacto em propostas comerciais Descomplicar.
|
||||
Baseado na filosofia canvas-design: design-forward, cada página comunica antes de ser lida.
|
||||
|
||||
---
|
||||
|
||||
## Filosofia de Design
|
||||
|
||||
**Princípio central:** o cliente forma opinião sobre a proposta nos primeiros 3 segundos.
|
||||
Cada página deve funcionar como imagem antes de funcionar como texto.
|
||||
|
||||
| Princípio | Aplicação |
|
||||
|-----------|-----------|
|
||||
| Visual-first | Imagem/composição comunica o tema antes do texto |
|
||||
| Texto mínimo | Menos palavras, mais impacto por palavra |
|
||||
| Espaço negativo | Respiração generosa — o vazio é parte do design |
|
||||
| Tipografia como design | O tipo de letra é um elemento visual, não só legível |
|
||||
| Paleta disciplinada | Máximo 3 cores por página (+ neutros) |
|
||||
|
||||
---
|
||||
|
||||
## Paleta Descomplicar
|
||||
|
||||
```python
|
||||
# Cores base da marca — aplicar consistentemente
|
||||
PALETA = {
|
||||
"dourado": "#C9A84C", # acento principal
|
||||
"dourado_lt": "#E8D5A3", # acento suave / fundo dourado
|
||||
"preto": "#0D0D0D", # fundo principal dark
|
||||
"cinza_esc": "#1A1A1A", # fundo secundário
|
||||
"cinza_med": "#3D3D3D", # separadores
|
||||
"cinza_lt": "#F5F5F5", # fundo light / texto em dark
|
||||
"branco": "#FFFFFF", # texto em dark, fundo clean
|
||||
}
|
||||
|
||||
# Tipografia (Nexa é a fonte da marca)
|
||||
FONTES = {
|
||||
"heading": "Nexa Bold",
|
||||
"subheading":"Nexa Light",
|
||||
"corpo": "Source Sans 3",
|
||||
"detalhe": "IBM Plex Mono", # para números, códigos
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Workflow: do conceito à página
|
||||
|
||||
```
|
||||
1. BRIEFING — que secção é esta? qual a mensagem principal?
|
||||
2. COMPOSIÇÃO — escolher layout base (ver tipos abaixo)
|
||||
3. HIERARQUIA — definir 3 níveis: âncora visual / título / detalhe
|
||||
4. COR — aplicar paleta com dominante + acento
|
||||
5. TIPOGRAFIA — tamanhos com contraste forte (ex: 72pt / 14pt)
|
||||
6. REFINAMENTO — remover tudo o que não é necessário
|
||||
7. EXPORTAÇÃO — PDF vector (300dpi para imprimir, 72dpi para digital)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Tipos de Página por Secção
|
||||
|
||||
### Capa de Proposta (primeira página)
|
||||
|
||||
**Objectivo:** impressionar, identificar o cliente, criar antecipação.
|
||||
|
||||
```python
|
||||
# Composição com python-reportlab
|
||||
from reportlab.lib.pagesizes import A4
|
||||
from reportlab.pdfgen import canvas
|
||||
from reportlab.lib.colors import HexColor
|
||||
|
||||
W, H = A4 # 595 x 842 pontos
|
||||
|
||||
def criar_capa(c: canvas.Canvas, nome_cliente: str, titulo: str):
|
||||
# Fundo preto total
|
||||
c.setFillColor(HexColor("#0D0D0D"))
|
||||
c.rect(0, 0, W, H, fill=1, stroke=0)
|
||||
|
||||
# Barra dourada lateral esquerda (elemento âncora)
|
||||
c.setFillColor(HexColor("#C9A84C"))
|
||||
c.rect(0, 0, 8, H, fill=1, stroke=0)
|
||||
|
||||
# Logo Descomplicar (topo direito)
|
||||
c.drawImage("assets/logo-white.png", W - 130, H - 60, 110, 40, mask="auto")
|
||||
|
||||
# Título em grande — dois terços da página
|
||||
c.setFillColor(HexColor("#FFFFFF"))
|
||||
c.setFont("Nexa-Bold", 52)
|
||||
# Quebra em 2 linhas se necessário
|
||||
linhas = quebrar_texto(titulo, max_chars=24)
|
||||
y = H * 0.55
|
||||
for linha in linhas:
|
||||
c.drawString(48, y, linha)
|
||||
y -= 64
|
||||
|
||||
# Nome do cliente — acento dourado
|
||||
c.setFillColor(HexColor("#C9A84C"))
|
||||
c.setFont("Nexa-Light", 18)
|
||||
c.drawString(48, H * 0.35, f"Preparado para {nome_cliente}")
|
||||
|
||||
# Data — rodapé discreto
|
||||
c.setFillColor(HexColor("#3D3D3D"))
|
||||
c.setFont("SourceSans3-Regular", 10)
|
||||
c.drawString(48, 32, f"Descomplicar® · descomplicar.pt · Março 2026")
|
||||
```
|
||||
|
||||
**Composição alternativa (versão light):**
|
||||
- Fundo branco com mancha fotográfica no lado direito (60% da largura)
|
||||
- Título sobreposto à foto com overlay escuro
|
||||
- Logo em preto, barra dourada mantida
|
||||
|
||||
### Separador de Secção
|
||||
|
||||
**Objectivo:** pausar o ritmo, anunciar o tema seguinte.
|
||||
|
||||
```python
|
||||
def criar_separador(c: canvas.Canvas, numero: str, titulo_seccao: str):
|
||||
# Fundo dourado total — inversão de cor
|
||||
c.setFillColor(HexColor("#C9A84C"))
|
||||
c.rect(0, 0, W, H, fill=1, stroke=0)
|
||||
|
||||
# Número enorme em background (marca de água visual)
|
||||
c.setFillColor(HexColor("#E8D5A3")) # dourado claro
|
||||
c.setFont("Nexa-Bold", 280)
|
||||
c.drawString(-20, H * 0.1, numero) # pode sair do bounds — intencional
|
||||
|
||||
# Título da secção — preto sobre dourado
|
||||
c.setFillColor(HexColor("#0D0D0D"))
|
||||
c.setFont("Nexa-Bold", 42)
|
||||
c.drawString(48, H * 0.45, titulo_seccao)
|
||||
|
||||
# Linha divisória fina
|
||||
c.setStrokeColor(HexColor("#0D0D0D"))
|
||||
c.setLineWidth(1)
|
||||
c.line(48, H * 0.42, W - 48, H * 0.42)
|
||||
```
|
||||
|
||||
### Infográfico de Dados
|
||||
|
||||
**Objectivo:** tornar números abstractos em narrativa visual.
|
||||
|
||||
```python
|
||||
def criar_infografico_metricas(c: canvas.Canvas, metricas: list[dict]):
|
||||
"""
|
||||
metricas = [
|
||||
{"valor": "3x", "label": "Aumento de tráfego", "icone": "trend"},
|
||||
{"valor": "47%", "label": "Redução de custo por lead", "icone": "savings"},
|
||||
{"valor": "12", "label": "Palavras-chave no Top 3", "icone": "star"},
|
||||
]
|
||||
"""
|
||||
# Fundo neutro quente
|
||||
c.setFillColor(HexColor("#F5F5F5"))
|
||||
c.rect(0, 0, W, H, fill=1, stroke=0)
|
||||
|
||||
# Título da página
|
||||
c.setFillColor(HexColor("#0D0D0D"))
|
||||
c.setFont("Nexa-Bold", 32)
|
||||
c.drawString(48, H - 80, "Resultados Projectados")
|
||||
|
||||
# Grid de métricas (3 colunas)
|
||||
col_w = (W - 96) / len(metricas)
|
||||
for i, m in enumerate(metricas):
|
||||
x = 48 + i * col_w
|
||||
y_center = H * 0.5
|
||||
|
||||
# Caixa de métrica
|
||||
c.setFillColor(HexColor("#FFFFFF"))
|
||||
c.roundRect(x + 8, y_center - 80, col_w - 16, 160, 12, fill=1, stroke=0)
|
||||
|
||||
# Valor principal — grande e dourado
|
||||
c.setFillColor(HexColor("#C9A84C"))
|
||||
c.setFont("Nexa-Bold", 56)
|
||||
c.drawCentredString(x + col_w / 2, y_center + 20, m["valor"])
|
||||
|
||||
# Label — preto, pequeno
|
||||
c.setFillColor(HexColor("#3D3D3D"))
|
||||
c.setFont("SourceSans3-Regular", 11)
|
||||
c.drawCentredString(x + col_w / 2, y_center - 20, m["label"])
|
||||
```
|
||||
|
||||
### Página de Pricing Visual
|
||||
|
||||
**Objectivo:** apresentar preços sem que pareçam uma tabela de custos.
|
||||
|
||||
```python
|
||||
def criar_pricing(c: canvas.Canvas, planos: list[dict]):
|
||||
"""
|
||||
planos = [
|
||||
{"nome": "Essencial", "preco": 450, "destaque": False,
|
||||
"items": ["SEO On-page", "Relatório mensal", "2 artigos/mês"]},
|
||||
{"nome": "Crescimento", "preco": 850, "destaque": True,
|
||||
"items": ["SEO completo", "Google Ads", "4 artigos/mês", "Dashboard BI"]},
|
||||
]
|
||||
"""
|
||||
# Fundo escuro para pricing
|
||||
c.setFillColor(HexColor("#0D0D0D"))
|
||||
c.rect(0, 0, W, H, fill=1, stroke=0)
|
||||
|
||||
card_w = (W - 96 - 16 * (len(planos) - 1)) / len(planos)
|
||||
|
||||
for i, p in enumerate(planos):
|
||||
x = 48 + i * (card_w + 16)
|
||||
y_top = H * 0.75
|
||||
|
||||
if p["destaque"]:
|
||||
# Card dourado para o plano recomendado
|
||||
c.setFillColor(HexColor("#C9A84C"))
|
||||
c.roundRect(x - 4, y_top - 4, card_w + 8, H * 0.5 + 8, 16, fill=1, stroke=0)
|
||||
texto_cor = HexColor("#0D0D0D")
|
||||
else:
|
||||
c.setFillColor(HexColor("#1A1A1A"))
|
||||
c.roundRect(x, y_top, card_w, H * 0.5, 12, fill=1, stroke=0)
|
||||
texto_cor = HexColor("#FFFFFF")
|
||||
|
||||
# Nome do plano
|
||||
c.setFillColor(texto_cor)
|
||||
c.setFont("Nexa-Bold", 20)
|
||||
c.drawString(x + 20, y_top + H * 0.5 - 44, p["nome"])
|
||||
|
||||
# Preço
|
||||
c.setFont("Nexa-Bold", 48)
|
||||
c.drawString(x + 20, y_top + H * 0.5 - 100, f"{p['preco']}€")
|
||||
c.setFont("SourceSans3-Regular", 11)
|
||||
c.drawString(x + 20, y_top + H * 0.5 - 118, "/ mês + IVA")
|
||||
|
||||
# Items incluídos
|
||||
c.setFont("SourceSans3-Regular", 12)
|
||||
y_item = y_top + H * 0.5 - 150
|
||||
for item in p["items"]:
|
||||
c.drawString(x + 28, y_item, f"— {item}")
|
||||
y_item -= 22
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Ferramentas: python-reportlab vs pptxgenjs
|
||||
|
||||
| Critério | python-reportlab | pptxgenjs (Node) |
|
||||
|----------|-----------------|------------------|
|
||||
| Output | PDF nativo | PPTX (editável) |
|
||||
| Controlo | Pixel-perfect | Aproximado |
|
||||
| Fontes custom | Suporte completo | Limitado |
|
||||
| Melhor para | Proposta final PDF | Template editável pelo cliente |
|
||||
| Ambiente | Servidor dev (`/root/Dev`) | Servidor dev ou local |
|
||||
|
||||
**Recomendação:** usar reportlab para proposta final; pptxgenjs se o cliente precisar de editar.
|
||||
|
||||
```bash
|
||||
# Instalar no servidor dev
|
||||
pip install reportlab Pillow
|
||||
|
||||
# Registar fontes Nexa
|
||||
from reportlab.pdfbase import pdfmetrics
|
||||
from reportlab.pdfbase.ttfonts import TTFont
|
||||
pdfmetrics.registerFont(TTFont("Nexa-Bold", "/root/Dev/assets/fonts/Nexa-Bold.ttf"))
|
||||
pdfmetrics.registerFont(TTFont("Nexa-Light", "/root/Dev/assets/fonts/Nexa-Light.ttf"))
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Regras de Composição (resumo operacional)
|
||||
|
||||
1. **Uma mensagem por página** — se precisas de duas frases para explicar, remove uma
|
||||
2. **Âncora visual primeiro** — o olho precisa de um ponto de entrada (número grande, foto, cor)
|
||||
3. **Contraste de escala** — combinar elemento 280pt com texto 12pt (não 24pt com 18pt)
|
||||
4. **Margens generosas** — margem mínima de 48pt em A4; prefere 64pt
|
||||
5. **Rodapé discreto** — página + marca em 9pt, nunca competir com conteúdo
|
||||
6. **Máximo 3 fontes** — Nexa Bold + Nexa Light + Source Sans 3 (IBM Plex Mono opcional para dados)
|
||||
7. **Alinhamento consistente** — escolher esquerda ou centrado para o documento inteiro
|
||||
|
||||
---
|
||||
|
||||
## Checklist de Qualidade
|
||||
|
||||
- [ ] Capa com nome do cliente e data correctos
|
||||
- [ ] Logo Descomplicar presente em todas as páginas (rodapé ou canto)
|
||||
- [ ] Paleta restrita a 3 cores por página
|
||||
- [ ] Nenhuma fonte genérica (Arial, Calibri, Times)
|
||||
- [ ] Espaço negativo generoso — sem páginas "cheias"
|
||||
- [ ] Preços em EUR sem decimais desnecessários (850EUR, não 850,00EUR)
|
||||
- [ ] PDF exportado em vector (não rasterizado)
|
||||
- [ ] Tamanho final < 10MB para envio por email
|
||||
- [ ] Testar visualização em modo claro e escuro (PDF viewer)
|
||||
|
||||
---
|
||||
|
||||
*Referência: premium-proposals v1.0 | 2026-03-10 | Descomplicar®*
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"task_id": null,
|
||||
"project_id": null,
|
||||
"customer_id": null,
|
||||
"gitea_repo": null
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
# skills
|
||||
|
||||
## Documentação
|
||||
|
||||
- [README](README.md)
|
||||
- [AGENTS](AGENTS.md)
|
||||
- [STATUS](STATUS.md)
|
||||
- [MEMORY](MEMORY.md)
|
||||
@@ -0,0 +1 @@
|
||||
## 2026-06-30 init | Estrutura padrão
|
||||
Reference in New Issue
Block a user