ads-dna

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Ads DNA — Brand DNA Extractor

Ads DNA — 品牌DNA提取工具

Extracts brand identity from a website and saves it as
brand-profile.json
for use by
/ads create
,
/ads generate
, and
/ads photoshoot
.
从网站提取品牌标识并保存为
brand-profile.json
,供
/ads create
/ads generate
/ads photoshoot
使用。

Quick Reference

快速参考

CommandWhat it does
/ads dna <url>
Full brand extraction →
brand-profile.json
/ads dna https://acme.com --quick
Fast extraction (homepage only)
命令功能
/ads dna <url>
完整品牌提取 →
brand-profile.json
/ads dna https://acme.com --quick
快速提取(仅首页)

Process

操作流程

Step 1: Collect URL

步骤1:收集URL

If the user hasn't provided a URL, ask:
"What website URL should I analyze for brand DNA? (e.g. https://yoursite.com)"
如果用户未提供URL,请询问:
"请提供要分析品牌DNA的网站URL?(例如:https://yoursite.com)"

Step 2: Fetch Pages

步骤2:获取页面内容

Use the WebFetch tool to retrieve each page. For each URL, use this fetch prompt:
"Return all visible text content, the full contents of any
<style>
blocks, inline
style=
attributes,
<meta>
tags, Google Fonts
@import
URLs, and any
og:image
values found on this page."
Fetch in this order:
  1. Homepage (
    <url>
    )
  2. About page — try
    <url>/about
    , then
    <url>/about-us
    , then
    <url>/our-story
  3. Product/Services page — try
    <url>/product
    , then
    <url>/products
    , then
    <url>/services
If
--quick
flag was provided
: fetch the homepage only — skip steps 2 and 3.
If a secondary page returns a 404 or redirect error, continue with fewer pages and note: "Secondary pages unavailable — extraction based on homepage only. Confidence may be lower."
使用WebFetch工具获取每个页面的内容。对于每个URL,使用以下获取提示:
"返回所有可见文本内容、所有
<style>
块的完整内容、内联
style=
属性、
<meta>
标签、Google Fonts的
@import
URL,以及页面中找到的所有
og:image
值。"
按以下顺序获取页面:
  1. 首页
    <url>
  2. 关于页面 — 尝试
    <url>/about
    ,然后是
    <url>/about-us
    ,再是
    <url>/our-story
  3. 产品/服务页面 — 尝试
    <url>/product
    ,然后是
    <url>/products
    ,再是
    <url>/services
如果提供了
--quick
参数
:仅获取首页内容 — 跳过步骤2和3。
如果二级页面返回404或重定向错误,则继续使用已获取的页面,并提示: "二级页面无法访问 — 仅基于首页进行提取,结果置信度可能较低。"

Step 2b: Capture Brand Screenshots

步骤2b:捕获品牌截图

After fetching pages, capture desktop screenshots of the website. These serve as visual style references during
/ads generate
— the same approach Pomelli uses to anchor ad images to the actual brand aesthetic.
Run for the homepage:
bash
python ~/.claude/skills/ads/scripts/capture_screenshot.py [url]
This saves
./brand-screenshots/[domain]_desktop.png
(default naming from the script).
Also attempt one secondary page (pricing or product page, whichever was accessible):
bash
python ~/.claude/skills/ads/scripts/capture_screenshot.py [url]/pricing
If
--quick
flag was provided
: skip screenshot capture entirely.
If capture fails (Playwright not installed, network error, JS-heavy SPA that times out):
  • Log:
    "Screenshot capture skipped — run: python3 -m playwright install chromium"
  • Continue without screenshots
  • Do NOT set the
    screenshots
    field in brand-profile.json
获取页面内容后,捕获网站的桌面端截图。这些截图将作为
/ads generate
过程中的视觉风格参考 — 与Pomelli的方法一致,确保广告图像与实际品牌美学保持一致。
对首页执行以下命令:
bash
python ~/.claude/skills/ads/scripts/capture_screenshot.py [url]
该命令会将截图保存为
./brand-screenshots/[domain]_desktop.png
(脚本默认命名规则)。
同时尝试捕获一个二级页面的截图(定价页或产品页,以可访问的页面为准):
bash
python ~/.claude/skills/ads/scripts/capture_screenshot.py [url]/pricing
如果提供了
--quick
参数
:完全跳过截图捕获步骤。
如果捕获失败(未安装Playwright、网络错误、JS渲染的SPA超时):
  • 记录日志:
    "截图捕获已跳过 — 请运行:python3 -m playwright install chromium"
  • 继续执行后续步骤,不使用截图
  • 不要在brand-profile.json中设置
    screenshots
    字段

Step 3: Extract Brand Elements

步骤3:提取品牌元素

From the fetched HTML, extract:
Colors:
  • og:image
    meta tag → analyze dominant colors (note 2-3 prominent hex values)
  • CSS
    background-color
    on
    body
    ,
    header
    ,
    .hero
    ,
    .btn-primary
  • CSS
    color
    on
    h1
    ,
    h2
    ,
    .btn
  • CSS
    border-color
    or
    background
    on
    .cta
    ,
    .button
  • Identify: primary (most prominent brand color), secondary (supporting colors), background, text
Typography:
  • @import url(https://fonts.googleapis.com/...)
    → extract font names from URL path
  • CSS
    font-family
    on
    h1
    ,
    h2
    ,
    body
    ,
    .headline
  • If Google Fonts URL contains
    family=Inter:wght@...
    , heading_font = "Inter"
Voice: Analyze hero headline, subheadline, About page intro, and CTA button text. Score each axis 1-10 using these heuristics:
SignalScore direction
Uses "you/your" frequentlyformal_casual → casual (+2)
Uses technical jargonexpert_accessible → expert (-2)
Short punchy sentences (≤8 words)bold_subtle → bold (+2)
Data/stats in herorational_emotional → rational (-2)
"Transform", "revolutionize", "disrupt"traditional_innovative → innovative (+2)
Customer testimonials leadrational_emotional → emotional (+2)
Industry awards, "trusted by X"traditional_innovative → traditional (-1)
Imagery style (from og:image and any visible hero image descriptions):
  • Photography vs. illustration vs. flat design
  • Subject matter (people, product, abstract, data)
  • Composition style (clean/minimal vs. busy/editorial)
Forbidden elements (infer from brand positioning):
  • Enterprise/B2B brands → add "cheesy stock photos", "consumer lifestyle imagery"
  • Healthcare → add "unqualified medical claims", "before/after imagery"
  • Finance → add "get rich quick imagery", "unrealistic wealth displays"
  • Consumer brands → usually no forbidden elements
从获取的HTML内容中提取以下元素:
颜色:
  • og:image
    元标签 → 分析主色调(记录2-3个突出的十六进制颜色值)
  • body
    header
    .hero
    .btn-primary
    的CSS
    background-color
    属性
  • h1
    h2
    .btn
    的CSS
    color
    属性
  • .cta
    .button
    的CSS
    border-color
    background
    属性
  • 区分:主色(最突出的品牌色)、辅助色(搭配色)、背景色、文本色
排版:
  • @import url(https://fonts.googleapis.com/...)
    → 从URL路径中提取字体名称
  • h1
    h2
    body
    .headline
    的CSS
    font-family
    属性
  • 如果Google Fonts URL包含
    family=Inter:wght@...
    ,则标题字体为"Inter"
语气风格: 分析英雄区标题、副标题、关于页简介和CTA按钮文本。 使用以下规则对每个维度评分1-10:
信号评分方向
频繁使用"you/your"正式/非正式 → 非正式(+2)
使用技术术语专业/易懂 → 专业(-2)
短句(≤8个单词)大胆/含蓄 → 大胆(+2)
英雄区包含数据/统计理性/感性 → 理性(-2)
使用"Transform"、"revolutionize"、"disrupt"传统/创新 → 创新(+2)
以客户评价开头理性/感性 → 感性(+2)
提及行业奖项、"trusted by X"传统/创新 → 传统(-1)
图像风格(基于og:image和可见的英雄区图像描述):
  • 摄影图 vs 插画 vs 扁平化设计
  • 主题内容(人物、产品、抽象、数据)
  • 构图风格(简洁/极简 vs 丰富/社论风)
禁用元素(根据品牌定位推断):
  • 企业/B2B品牌 → 添加"俗气库存图"、"消费者生活方式图像"
  • 医疗保健品牌 → 添加"不合格医疗声明"、"前后对比图"
  • 金融品牌 → 添加"快速致富图像"、"不切实际的财富展示"
  • 消费品牌 → 通常无禁用元素

Step 4: Build brand-profile.json

步骤4:构建brand-profile.json

Read
~/.claude/skills/ads/references/brand-dna-template.md
for the exact schema.
Construct the JSON object following the schema precisely. Use
null
for any field that cannot be confidently extracted — do not guess.
Example of a low-confidence field:
json
"typography": {
  "heading_font": null,
  "body_font": "system-ui",
  "pairing_descriptor": "system default (Google Fonts not detected)"
}
参考
~/.claude/skills/ads/references/brand-dna-template.md
中的精确 schema。
严格按照schema构建JSON对象。对于无法确定的字段,使用
null
填充 — 不要猜测。
低置信度字段示例:
json
"typography": {
  "heading_font": null,
  "body_font": "system-ui",
  "pairing_descriptor": "系统默认字体(未检测到Google Fonts)"
}

Step 5: Write brand-profile.json

步骤5:写入brand-profile.json

Write the JSON to
./brand-profile.json
in the current working directory (where the user is running Claude Code).
If screenshots were captured successfully in Step 2b, include a
screenshots
field:
json
"screenshots": {
  "homepage": "./brand-screenshots/[domain]_desktop.png",
  "secondary": ["./brand-screenshots/[domain]_pricing_desktop.png"]
}
Omit the
screenshots
field entirely if Step 2b was skipped or failed.
将JSON文件写入当前工作目录(用户运行Claude Code的目录),命名为
./brand-profile.json
如果步骤2b成功捕获了截图,则在JSON中添加
screenshots
字段:
json
"screenshots": {
  "homepage": "./brand-screenshots/[domain]_desktop.png",
  "secondary": ["./brand-screenshots/[domain]_pricing_desktop.png"]
}
如果步骤2b被跳过或失败,则完全省略
screenshots
字段。

Step 6: Confirm and Summarize

步骤6:确认并总结

Show the user:
✓ brand-profile.json saved to ./brand-profile.json

Brand DNA Summary:
  Brand: [brand_name]
  Voice: [descriptor 1], [descriptor 2], [descriptor 3]
  Primary Color: [hex]
  Typography: [heading_font] / [body_font]
  Target: [age_range] [profession]
  Screenshots: [N captured → ./brand-screenshots/] OR [skipped]

Run `/ads create` to generate campaign concepts from this profile.
向用户展示以下内容:
✓ brand-profile.json已保存至./brand-profile.json

品牌DNA摘要:
  品牌:[brand_name]
  语气风格:[描述符1], [描述符2], [描述符3]
  主色:[hex值]
  排版:[标题字体] / [正文字体]
  目标受众:[年龄范围] [职业]
  截图:[已捕获N张 → ./brand-screenshots/] 或 [已跳过]

运行`/ads create`以基于此配置文件生成广告活动方案。

Limitations

局限性

  • Sparse content: Sites with <200 words of body text produce lower-confidence profiles. Note: "Low confidence extraction — limited content available for analysis."
  • Dynamic sites: JavaScript-rendered content may not be captured. Playwright is not used by default. If the site appears to be SPA/React with no static HTML, note this.
  • Multi-brand enterprises: This tool creates one profile per URL. Run separately for each brand/product line.
  • Dark mode sites: If body background is #333 or darker, swap background/text values.
  • CSS-in-JS: Modern React sites may not have extractable CSS. Use og:image colors as fallback.
  • 内容稀疏:正文文本少于200词的网站会生成置信度较低的配置文件。需提示:"提取结果置信度低 — 可分析的内容有限。"
  • 动态网站:JavaScript渲染的内容可能无法被捕获。默认不使用Playwright。如果网站是SPA/React且无静态HTML,需提示此情况。
  • 多品牌企业:此工具每个URL生成一个配置文件。如需分析多个品牌/产品线,请分别运行工具。
  • 深色模式网站:如果页面背景色为#333或更深,需交换背景色和文本色的值。
  • CSS-in-JS:现代React网站可能无法提取CSS。此时使用og:image中的颜色作为备选。

brand-profile.json Schema

brand-profile.json Schema

json
{
  "schema_version": "1.0",
  "brand_name": "string",
  "website_url": "string",
  "extracted_at": "ISO-8601",
  "voice": {
    "formal_casual": 1-10,
    "rational_emotional": 1-10,
    "playful_serious": 1-10,
    "bold_subtle": 1-10,
    "traditional_innovative": 1-10,
    "expert_accessible": 1-10,
    "descriptors": ["adjective1", "adjective2", "adjective3"]
  },
  "colors": {
    "primary": "#hexcode or null",
    "secondary": ["#hex1", "#hex2"],
    "forbidden": ["#hex or color name"],
    "background": "#hexcode",
    "text": "#hexcode"
  },
  "typography": {
    "heading_font": "Font Name or null",
    "body_font": "Font Name or system-ui",
    "pairing_descriptor": "brief description"
  },
  "imagery": {
    "style": "professional photography | illustration | flat design | mixed",
    "subjects": ["subject1", "subject2"],
    "composition": "brief description",
    "forbidden": ["element1", "element2"]
  },
  "aesthetic": {
    "mood_keywords": ["keyword1", "keyword2", "keyword3"],
    "texture": "minimal | textured | mixed",
    "negative_space": "generous | moderate | dense"
  },
  "brand_values": ["value1", "value2", "value3"],
  "target_audience": {
    "age_range": "e.g. 25-45",
    "profession": "brief description",
    "pain_points": ["pain1", "pain2"],
    "aspirations": ["aspiration1", "aspiration2"]
  }
}
json
{
  "schema_version": "1.0",
  "brand_name": "string",
  "website_url": "string",
  "extracted_at": "ISO-8601",
  "voice": {
    "formal_casual": 1-10,
    "rational_emotional": 1-10,
    "playful_serious": 1-10,
    "bold_subtle": 1-10,
    "traditional_innovative": 1-10,
    "expert_accessible": 1-10,
    "descriptors": ["adjective1", "adjective2", "adjective3"]
  },
  "colors": {
    "primary": "#hexcode or null",
    "secondary": ["#hex1", "#hex2"],
    "forbidden": ["#hex or color name"],
    "background": "#hexcode",
    "text": "#hexcode"
  },
  "typography": {
    "heading_font": "Font Name or null",
    "body_font": "Font Name or system-ui",
    "pairing_descriptor": "brief description"
  },
  "imagery": {
    "style": "professional photography | illustration | flat design | mixed",
    "subjects": ["subject1", "subject2"],
    "composition": "brief description",
    "forbidden": ["element1", "element2"]
  },
  "aesthetic": {
    "mood_keywords": ["keyword1", "keyword2", "keyword3"],
    "texture": "minimal | textured | mixed",
    "negative_space": "generous | moderate | dense"
  },
  "brand_values": ["value1", "value2", "value3"],
  "target_audience": {
    "age_range": "e.g. 25-45",
    "profession": "brief description",
    "pain_points": ["pain1", "pain2"],
    "aspirations": ["aspiration1", "aspiration2"]
  }
}