Resolve dor real: clonar estilos visuais de sites e slides para propostas. Tentativas anteriores (Penpot, scrapers HTML, Figma import) falharam porque tentavam reproduzir layouts. Esta skill extrai tokens (cores, fontes, espaçamento, raios, sombras) e alimenta gerador (Stitch / design-engine). Modos: - /clone-style web <url>: extract-web-tokens.js via chrome real (CSS computado) - /clone-style slides <pptx>: extract-pptx-theme.py (theme1.xml + slideMasters) - /clone-style apply <tokens.json>: mapeia para Stitch / design-engine / pptx Validado: PPTX (Calibri/Calibri Light + 6 accent colors do Office default theme). Web: aguarda primeiro teste end-to-end com browser real. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
9.9 KiB
name, description
| name | description |
|---|---|
| clone-style | 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". |
/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
-
Abrir URL no Chrome real via
mcp__claude-in-chrome__navigate(preferido — captura sessões logged-in se necessário) oumcp__chrome-devtools__navigate_page. -
Aguardar render completo (
wait_for"load" + 2s extra para JS). -
Injectar script de extracção via
mcp__claude-in-chrome__javascript_tooloumcp__chrome-devtools__evaluate_script. O script está emreferences/extract-web-tokens.js. Cola-o dentro do tool call. -
O script devolve JSON estruturado com:
colors: paleta deduplicada + ranking por frequência (top 12)fonts: famílias únicas + tamanhos + pesos + line-heightsspacing: gaps/paddings/margins agrupados (encontra grid base 4px/8px)borderRadius: pequeno/médio/grande/full (clusters)shadows: box-shadows únicascomponentes: HTML+CSS de buttons, cards, nav, hero (capturados como referência)
-
Capturar screenshots dos componentes detectados via
mcp__chrome-devtools__take_screenshotoumcp__claude-in-chrome__computer(full + por componente). -
Mapear para Stitch (ver secção "Mapeamento Stitch" abaixo) — cores → primary seed, fonte mais usada → enum match, raio dominante → ROUND_*.
-
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
-
Verificar input existe e é PPTX válido (
unzip -l <file>para listar entradas). -
Extrair em tmp:
unzip -o <file> -d /tmp/clone-style-pptx-<ts>/. -
Parsear
theme1.xml(Python ou xmllint):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') -
Parsear
slideMaster1.xmlpara layouts dominantes (background, posições, sizes default). -
Output
tokens.jsonno mesmo formato do Modo 1 (para queapplyseja 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) + opcionaisoverridePrimaryColor/overrideSecondaryColor/overrideTertiaryColor/overrideNeutralColor headlineFont/bodyFont/labelFontde enum fixo (29 Google Fonts: INTER, ROBOTO, MANROPE, GEIST, etc.)roundness: ROUND_4 / ROUND_8 / ROUND_12 / ROUND_FULLcolorMode: LIGHT / DARKdesignMd: markdown livre para tudo o que não cabe nos campos acima
Mapeamento Stitch:
tokens.colors.dominant → customColor (seed)
tokens.colors.top[1..3] → overridePrimary/Secondary/Tertiary
tokens.colors.neutral → overrideNeutralColor
tokens.fonts.headline.family
→ match com enum Stitch (fuzzy: "Helvetica" → INTER, "Söhne" → INTER, etc.)
→ headlineFont
tokens.fonts.body.family
→ match enum → bodyFont
tokens.borderRadius.dominant
→ 4px → ROUND_4
→ 8-10px → ROUND_8
→ 12-14px → ROUND_12
→ ≥16px ou full → ROUND_FULL
tokens.background.dark? → colorMode: DARK, else LIGHT
# Tudo o resto vai para designMd:
designMd: |
## Estilo extraído de <fonte>
### Tipografia adicional
- Display: <font> <size> <weight>
- Caption: <font> <size> <weight>
### Espaçamento
Grid base: <Npx>
Escala: 4, 8, 16, 24, 32, 48, 64
### Sombras
- sm: <box-shadow>
- md: <box-shadow>
- lg: <box-shadow>
### Tom visual
<descrição em prosa: minimalista, denso, colorido, monocromático, etc.>
Depois chama mcp__stitch__create_design_system com este payload.
B) design-engine (brand pack)
Cria um JSON brand pack em /media/ealmeida/Dados/Hub/04-Recursos/Design/brands/<nome>.json com formato:
{
"name": "<nome>",
"source": "cloned from <url|pptx>",
"extracted_at": "2026-04-07",
"colors": { "primary": "#...", "secondary": "#...", "neutral": "#...", "accent": "#..." },
"fonts": { "headline": "Inter", "body": "Inter" },
"borderRadius": "8px",
"tone": "minimalista, profissional, denso"
}
Depois mcp__design-engine__brand_load(<nome>) para usar em generate_image.
C) pptx-generator (slides)
Aplica os tokens via XML manipulation no template Descomplicar (ver /pptx-generator). Substitui:
- Cores accent1-6 do
theme1.xmlpelos extraídos - Fontes major/minor pelas extraídas
- Mantém layouts/positioning do template Descomplicar (não copia layouts da fonte original — só estilo)
Mapeamento de fontes (fuzzy → Stitch enum)
Quando tokens.fonts.headline.family não está no enum Stitch, mapear:
| Família detectada | Stitch enum |
|---|---|
| Helvetica, Helvetica Neue, Arial, sans-serif genérico | INTER |
| Söhne, Inter, system-ui | INTER |
| Roboto, Roboto Flex | (não existe — usar INTER) |
| SF Pro, -apple-system | INTER |
| GT Walsheim, Geist, Mona Sans | GEIST |
| Manrope | MANROPE |
| Plus Jakarta, Jakarta | PLUS_JAKARTA_SANS |
| DM Sans | DM_SANS |
| IBM Plex Sans | IBM_PLEX_SANS |
| Sora | SORA |
| Times, serif genérico | NEWSREADER |
| Garamond, EB Garamond | EB_GARAMOND |
| Playfair, Domine | DOMINE |
Se nenhum match óbvio, default INTER (mais neutro). Adicionar nota em designMd com a fonte original detectada.
Anti-patterns
| Não fazer | Razão |
|---|---|
| Tentar reproduzir layout pixel a pixel | Impossível e gera "AI slop" |
Usar cssstats.com ou scrapers HTML estáticos |
Falham em sites JS-rendered (Next.js, React, etc.) |
| Importar HTML inteiro como Stitch screen | Stitch não importa HTML; gera de prompt+tokens |
Aplicar Stitch design-system sem customColor válido |
Validation error — customColor é obrigatório |
Esquecer de usar designMd para tokens fora do enum |
Perde-se 50% da informação extraída |
Validação (critérios para "OK")
Antes de declarar a clonagem completa:
- ✅
tokens.jsonexiste e temcolors,fonts,borderRadiusno mínimo - ✅ Pelo menos 1 screenshot guardado
- ✅ Mapeamento Stitch produz
customColorválido (hex format) - ✅ Pelo menos 1 fonte mapeada para enum Stitch
- ✅
designMdtem ≥3 secções (tipografia, espaçamento, tom) - ✅ Se modo
apply: validação visual pelo utilizador antes de marcar "concluído"
Exemplos práticos
Clonar Linear
/clone-style web https://linear.app
Esperado: paleta dominante azul/roxo, fontes Inter ou similar, raios 6-8px, dark mode default.
Clonar template cliente
/clone-style slides ~/Downloads/cliente-deck.pptx
Esperado: cores accent do tema PPTX, fontes major/minor, proposta de paleta unificada.
Aplicar a novo projecto Stitch
/clone-style apply ~/.claude-work/clone-style/linear-app-20260407/tokens.json
Cria design system Stitch + brand pack design-engine.
Referências internas
references/extract-web-tokens.js— script JS de extracção CSS computadoreferences/extract-pptx-theme.py— script Python para parsear theme1.xml~/.claude-work/clone-style/— cache de extracções (timestamped)
Versão: 1.0.0 | Data: 2026-04-07 | Autor: Descomplicar (sessão 5) Origem: Necessidade real — clonagem de estilos em propostas comerciais. Substitui tentativas falhadas com Penpot, scrapers HTML, screenshots+AI, Figma import.