Design + Build

COMPANYMODEL

I built a system that extracts, catalogs, and generates marketing content for a large fintech company's website.

This case study describes work done at Block, Inc. (Square). It covers process and design thinking only. Specific metrics, screenshots, and proprietary details are omitted per NDA. More information available upon request.

Role Design + Build
Year 2026
Architecture LLM Pipeline Knowledge Graph Data Visualization

The Problem

The company's marketing site had hundreds of pages across multiple regions and locales. Individual pages were well-written, but there was no machine-readable model of what the site actually said - no documented rules for how content was structured, what entities appeared where, or how products were described across locales. Without that, there was no way to author at the system level and no way to generate a new page without starting from scratch.

The Approach

Instead of writing pages one at a time, I built a system that extracts what the site already says, organizes it into reusable content entities (features, benefits, CTAs, pricing, testimonials), and lets an LLM compose new pages from those entities. The goal: make content authoring data-driven instead of ad hoc.

The 4-Layer Architecture

1

Extraction

Crawl the site and use an LLM to extract structured entities from each page. This turns unstructured marketing copy into machine-readable data.

2

Canonical Model

A deduplicated entity database that spans pages and locales. One source of truth for what the company says about each product, feature, and benefit.

3

Generative Content

An LLM assembles page layouts from real entities in the database. New pages are composed from verified content, not invented from scratch.

4

Adaptive Layer

Personalization based on audience and context at runtime. This layer is planned but not yet built. The architecture is designed to support it.

System Pipeline
======================== URLs ----> [ Crawler + LLM Extractor ] | v structured entities | v +-------------+ | Postgres | +------+------+ | +------------+------------+ | | v v ==================== ==================== Entity Browser scaffold(product, audience, locale) Heatmaps | Product DNA v Knowledge Graph +-----------------------------------+ | hero | features | pricing | cta | +-----------------------------------+

I designed and built layers 1 through 3. The key design decision was defining clear boundaries between layers so each one can be changed independently.

How I Worked with AI

1
Query the data before designing anything

I sat with Claude and wrote SQL against the extracted entities. I wanted to see what the actual distributions looked like before committing to any visualization. Some ideas I had going in were wrong. Cheaper to find that out with a query than with a prototype.

2
Ship the CLI first, then build the UI

The extraction pipeline started as a command-line tool: paste a URL, get structured entities back as JSON. No interface, just working data. Once I could see the shape of what the extractor produced, the dashboard layout followed from that shape.

3
Write a plan before every Claude session

Each chunk of work started as a written plan I pasted into Claude: here's what exists now, here's what needs to change, here's what done looks like. The plans got shorter over time as the codebase became more self-explanatory, but writing the context first never stopped being useful.

Built-In Feedback

I added a toggle-able annotation layer to the dashboard prototype. When toggled on, open design questions appeared highlighted in red, positioned next to the data they referred to. When toggled off, the dashboard looked clean. For example, a question like "Should pricing be its own entity type or a property of a product?" appeared right on the pricing section. This let the prototype serve as both a working tool and a design review surface, instead of keeping feedback in a separate document.

Design Decisions

Layer 2 - The Dashboard

The dashboard's primary job is to answer: where are we missing content? The main view is a heatmap showing products vs. entity types (features, benefits, CTAs, etc.) across locales. Empty cells mean gaps. The navigation links to deeper views like funnel analysis and the entity graph, but the heatmap is the landing page.

Company Model
Dashboard Explorer Graph
All Golden Notes
3,060
Pages Crawled
8,412
Entities
18
Products
Content Building Blocks
feature2,841 product412 benefit1,209 cta890 pricing318 testimonial167 statistic94
Product DNA
product-a
product-b
product-c
product-d
product-e
Top CTAs
Get started
Contact
Learn more
Try free
Locale Coverage
en-US
en-GB
fr-FR
ja-JP
Translation Gaps
es-ES
fr-CA
ja-JP
en-AU
Audience DNA
feat
prod
ben
cta
price
test
stat
segment-a
segment-b
segment-c
segment-d
Explorer View
Funnel Stages
Entry
Research
Closer
Refine
Type...
Locale...
Clear filters
online-payments
feature
42 instances
get-started-free
cta
89 instances
no-monthly-fees
benefit
31 instances
free-plus-tiers
pricing
18 instances
Knowledge Graph View
Type filter
Edge filter
847 nodes, 312 contains, 94 co-occurs, 41 cross-page
online-payments
feature
contains: 12 · co-occurs: 4 · cross-page: 2

Structured views first, graph second

A force-directed graph looks impressive, but users needed to answer "where do we have a gap?" Structured views like heatmaps answer that faster, so they got the front page.

Make gaps obvious

Most heatmaps make empty cells invisible. In this design, empty cells have a visible dashed outline so content gaps are just as readable as content that exists.

Wait for real data before demoing generation

I held off building the content generation layer (Layer 3) until the entity database (Layer 2) had enough volume. Demoing generation on thin data would have set wrong expectations about quality.

Reflection

Understand the data first. The design follows from its shape.

The part I'm most proud of is the separation between layers. You can swap out the LLM in Layer 1 and Layers 2 through 4 keep working unchanged. That modularity works because I defined the boundaries early and stuck with them.

Related Open-Source Project

I built a similar content extraction and knowledge graph system as a personal project. It uses the same approach of crawling sites, extracting entities, and building a queryable model. Full source code available: SiteMapper on GitHub.