How the Diagram Design Brand Onboarding System Extracts Tokens from a Website

The brand onboarding system in Diagram Design extracts semantic color and font tokens from live websites by fetching the HTML and screenshot, parsing CSS custom properties or computing color histograms, mapping colors to semantic roles like paper and accent, and writing validated tokens into style-guide.md.

The cathrynlavery/diagram-design repository automates brand identity capture through a deterministic pipeline that converts live web pages into reusable design tokens. This system, documented in skills/diagram-design/references/onboarding.md, enables the skill to onboard brands directly from URLs without manual color picking.

Fetching the Target Website

The extraction process begins by retrieving the target website's visual and structural data. The system executes an agent-browser command to capture both the rendered HTML and a screenshot of the page.

agent-browser navigate https://example.com --screenshot out.png --html out.html

If the browser agent is unavailable, the system falls back to a standard HTTP fetch operation. This dual-capture approach ensures that both the document structure and the visual rendering are available for analysis, as specified in the URL-onboarding section of the onboarding documentation.

Parsing CSS and Visual Data

Once fetched, the system analyzes three potential sources for color and font information.

Extracting CSS Custom Properties

The primary source for color tokens is the CSS custom properties defined in :root or other style blocks. The parser inspects the rendered stylesheet for variable definitions such as --accent or --primary.

When custom properties exist, they take precedence as the authoritative brand colors.

Analyzing the Screenshot

If CSS custom properties are absent, the system computes a color histogram from the screenshot image. This analysis identifies dominant hues by examining pixel frequency, providing a fallback mechanism for sites without explicit design tokens.

Reading Computed HTML Styles

The system extracts additional context from computed styles:

  • The <body> background color
  • Primary text colors
  • Prominent CTA or link colors

These values serve as inputs when CSS variables are incomplete or missing.

Mapping Colors and Fonts to Semantic Roles

The extracted raw values are mapped to Diagram Design's semantic palette through deterministic heuristics.

Color Roles:

Semantic Role Source Heuristic
paper Background of <body> or the largest area color
ink Primary body text color
muted Secondary/caption color
accent Most-used brand color (CTA button, link, heading accent)
paper-2 Container/card background (slightly darker than paper)
rule Border/hairline color (converted to rgba of ink at ~12% opacity)

Font Family Extraction:

Font families are collected from specific HTML elements:

  • <h1> tags → title family
  • <body> tags → node-name family
  • <code> or <pre> tags → sublabel family

The system implements an Exact-font gate that validates reproducibility. Only fonts available through services like Google Fonts are recorded; unsupported fonts are marked as fallback to ensure the diagrams remain portable.

Validating and Persisting Tokens

Before writing to storage, the system validates the extracted tokens against accessibility and brand consistency rules.

Contrast Checks: The system verifies that color combinations meet WCAG AA standards (minimum 4.5:1 contrast ratio) and checks color saturation levels for brand appropriateness.

Diff Preview: A proposed diff of the new token table is generated and displayed to the user for approval, showing changes to existing values versus the newly extracted ones.

Writing to Storage: Upon approval, the skill writes the validated token rows into skills/diagram-design/references/style-guide.md. The system can also save the configuration as a named profile in profiles.md for reusable client branding.

Implementation Examples

Running the Browser Fetch


# Pull the live site and store HTML + screenshot

agent-browser navigate https://mycompany.com \
    --screenshot site.png \
    --html site.html

Python Color Extraction Logic

This minimal Python implementation mirrors the token extraction heuristics found in the source:

import json
from pathlib import Path
from bs4 import BeautifulSoup
import requests
import colorsys

def fetch_page(url: str) -> str:
    resp = requests.get(url, timeout=10)
    resp.raise_for_status()
    return resp.text

def extract_css_custom_props(html: str) -> dict:
    """Return a map of --var-name → hex colour."""
    soup = BeautifulSoup(html, "html.parser")
    props = {}
    for style in soup.find_all("style"):
        for line in style.string.splitlines():
            if line.strip().startswith("--"):
                name, value = line.split(":", 1)
                props[name.strip()] = value.strip().rstrip(";")
    return props

def dominant_color_from_image(img_path: Path) -> str:
    """Simple histogram-based colour picker."""
    from PIL import Image
    img = Image.open(img_path).convert("RGB")
    colors = img.getcolors(maxcolors=1000000)
    most_common = max(colors, key=lambda c: c[0])[1]
    return f"#{most_common[0]:02x}{most_common[1]:02x}{most_common[2]:02x}"

# Example usage

url = "https://example.com"
html = fetch_page(url)
css_props = extract_css_custom_props(html)

if "--accent" in css_props:
    accent = css_props["--accent"]
else:
    accent = dominant_color_from_image(Path("site.png"))
print("Detected accent colour:", accent)

Generating Token Diffs

def token_table_diff(old: dict, new: dict) -> str:
    lines = ["| Role | Old | New |"]
    for role in ["paper","ink","muted","accent","paper-2","rule"]:
        old_val = old.get(role, "-")
        new_val = new.get(role, "-")
        line = f"| `{role}` | `{old_val}` | `{new_val}` |"
        lines.append(line)
    return "\n".join(lines)

old_tokens = {"paper":"#f5f4ed","ink":"#0b0d0b","accent":"#f7591f"}
new_tokens = {"paper":"#f8f6f0","ink":"#111111","accent":"#c73a2b"}
print(token_table_diff(old_tokens, new_tokens))

Summary

  • The brand onboarding system fetches websites using agent-browser or HTTP requests to capture both HTML and screenshots.
  • Color extraction prioritizes CSS custom properties, falling back to screenshot histogram analysis when variables are absent.
  • Extracted values map to semantic roles (paper, ink, accent, etc.) based on DOM element analysis and visual heuristics.
  • Font families are extracted from specific HTML tags with an Exact-font gate filtering unsupported typefaces.
  • All token changes are validated for contrast accessibility (AA ≥ 4.5:1) before writing to style-guide.md.

Frequently Asked Questions

What file stores the extracted brand tokens?

The system writes extracted tokens to skills/diagram-design/references/style-guide.md. This file maintains the semantic token table that defines the visual identity for all generated diagrams.

How does the system handle fonts that cannot be reproduced?

The Exact-font gate filters font families during extraction. Only fonts available through reproducible sources (such as Google Fonts) are recorded. If a font cannot be reliably rendered, the system marks the role as fallback to prevent broken typography in outputs.

What happens if a website does not use CSS custom properties?

When CSS custom properties are missing, the system computes a color histogram from the screenshot image to infer dominant hues. It also analyzes computed styles from the HTML body, text elements, and interactive components to derive the semantic color palette without relying on CSS variables.

Where is the onboarding process documented?

The complete specification resides in skills/diagram-design/references/onboarding.md, which details the three onboarding methods (URL, installed skill, and local folder) and their shared token-extraction heuristics. Additional context appears in skills/diagram-design/SKILL.md regarding the brand token onboarding capability.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →