How the Brand Onboarding Process Extracts Colors from a Website for Diagram Design
The brand onboarding process fetches a website's HTML, parses its CSS to extract all color values, ranks them by frequency and visual prominence, then maps the top five colors to semantic design tokens.
This automated pipeline—implemented in the cathrynlavery/diagram-design repository—eliminates manual color entry by transforming any public website into a reusable brand palette. The entire workflow completes in approximately 60 seconds and writes directly to the skill's style guide.
The 10-Step Color Extraction Pipeline
The brand onboarding process follows a deterministic, self-contained workflow defined in skills/diagram-design/references/onboarding.md:
1. User URL Input
The skill prompts for a publicly accessible website address. Example: https://mybrand.com.
2. HTML Retrieval
The system issues an HTTP GET request using Python's httpx or urllib.request to download the page markup.
3. Stylesheet Discovery
BeautifulSoup parses the HTML to locate:
<link rel="stylesheet">tags for external CSS- Inline
<style>blocks embedded in the document
4. CSS Aggregation
External stylesheets are fetched and concatenated with inline styles. The combined CSS is normalized—comments, whitespace, and media-query wrappers are stripped.
5. Color Parsing
A regular expression scan extracts every CSS color literal:
- Hex codes:
#rrggbb,#rgb - Functions:
rgb(),hsl() - Named colors:
aliceblue,antiquewhite,aqua, etc.
The parser prioritizes properties associated with brand visibility: background-color, color, border-color, and fill.
6. Frequency Scoring
Each color occurrence is tallied. Heuristics boost weights for colors applied to high-visibility selectors like a, button, and h1.
7. Top-N Selection
By default, the pipeline selects the five most common colors and assigns them to semantic roles:
paper— background/base colorink— primary text coloraccent— highlight/CTA colormuted— secondary/subdued colorlink— hyperlink color
8. Font Family Extraction
A parallel scan extracts font-family declarations from body and heading selectors to identify the primary typeface.
9. Style Guide Generation
The extracted tokens replace defaults in skills/diagram-design/references/style-guide.md. A fidelity receipt records the source URL and extracted values.
10. Profile Persistence (Optional)
Users may save results as a named profile to ~/.diagram-design/profiles/<slug>.md for automatic application to future diagrams.
Implementation: Core Code Components
The following Python snippets mirror the internal logic used by the diagram-design skill.
Fetch and Parse HTML
import httpx
from bs4 import BeautifulSoup
def fetch_html(url: str) -> str:
"""Download the page HTML."""
resp = httpx.get(url, timeout=10.0)
resp.raise_for_status()
return resp.text
Collect CSS from All Sources
def collect_css(html: str, base_url: str) -> str:
"""Gather inline <style> blocks and external CSS files."""
soup = BeautifulSoup(html, "html.parser")
css_parts = []
# Inline styles
for style_tag in soup.find_all("style"):
css_parts.append(style_tag.string or "")
# External stylesheets
for link in soup.select('link[rel="stylesheet"]'):
href = link.get("href")
if not href:
continue
css_url = httpx.URL(href, base_url=base_url)
css_parts.append(httpx.get(str(css_url)).text)
return "\n".join(css_parts)
Extract and Rank Colors
import re
from collections import Counter
COLOR_RE = re.compile(
r"""(?i)
\#([0-9a-f]{3}|[0-9a-f]{6})|
rgb\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*\)|
hsl\(\s*\d+\s*,\s*\d+%?,\s*\d+%?\)|
(aliceblue|antiquewhite|aqua|...|yellow) # abbreviated list
""", re.VERBOSE)
def extract_colors(css: str) -> list[str]:
"""Return a list of all colour literals found in the CSS."""
return COLOR_RE.findall(css)
def rank_colors(colors: list[str]) -> list[tuple[str, int]]:
"""Count occurrences and return colours sorted by frequency."""
return Counter(colors).most_common()
def map_to_tokens(top_colors: list[tuple[str, int]]) -> dict:
"""Map the five most common colours to semantic tokens."""
tokens = ["paper", "ink", "accent", "muted", "link"]
return {token: color for token, color in zip(tokens, [c for c, _ in top_colors])}
Command-Line Usage
Execute the full pipeline via the skill's built-in command:
diagram-design onboard https://example.com
This prints a summary report and updates style-guide.md with extracted tokens.
To preserve results for reuse:
diagram-design onboard https://example.com --save my-brand
The saved profile enables automatic brand application without re-running extraction.
Key Source Files
| File | Purpose |
|---|---|
skills/diagram-design/references/onboarding.md |
Complete specification of URL-to-tokens flow, color-extraction heuristics, and ranking algorithm |
skills/diagram-design/references/style-guide.md |
Semantic token definitions (paper, ink, accent, muted, link) populated by onboarding |
skills/diagram-design/SKILL.md |
High-level capability description linking to onboarding functionality |
Summary
- The brand onboarding process extracts colors from websites through automated CSS parsing and frequency analysis
- Five semantic tokens (
paper,ink,accent,muted,link) receive the most prominent colors - The pipeline completes in ~60 seconds and writes directly to
style-guide.md - Profiles enable persistent brand reuse via
~/.diagram-design/profiles/ - Implementation relies on BeautifulSoup, httpx, and regex-based color parsing
Frequently Asked Questions
What color formats does the brand onboarding process support?
The parser recognizes hex shorthand (#rgb), hex standard (#rrggbb), rgb() functions, hsl() functions, and CSS named colors. All values are extracted as strings and ranked by occurrence count before token assignment.
How does the system decide which colors are "brand" colors?
Frequency is the primary signal—colors appearing most often in the CSS are assumed primary. Heuristic weights boost scores for colors applied to navigation elements (a), buttons (button), and headings (h1), under the assumption that these receive deliberate brand treatment.
Can I modify the number of extracted colors?
The default selects five colors mapped to fixed semantic tokens. To customize, edit the tokens list in map_to_tokens() and adjust the slice operation on top_colors before the zip() call.
Where are extracted brand profiles stored?
Named profiles persist to ~/.diagram-design/profiles/<slug>.md when using the --save flag. These Markdown files contain the full token set and fidelity receipt, enabling version-controlled brand management and team sharing.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →