0.0 Strategy
1391:22094 · Figma source
JPMC had more than 75 brand kits like this Payments example. Reviewers and designers still had to interpret that guidance manually, which made review slow and early concept work hard to scale.
The technical question became: can we turn guideline pages, examples, and tacit brand knowledge into a structured system that helps with both compliance review and generation?
A few examples from the Payments guideline kit, grouped by the kind of brand knowledge the system needed to understand.
The intent and identity rules the system needed to preserve.
The concrete visual rules that mattered most for retrieval, compliance checks, and citations.
Examples showing how the rules come through in imagery, icons, motion, and final applications.
This opening map frames the JPMC engagement the way I would talk through it: an ambiguous AI ask, hands-on architecture, stakeholder alignment, and a concrete outcome through a brand-knowledge system.
%%{init: {'theme': 'base', 'themeVariables': { 'fontFamily': '"IBM Plex Sans", ui-sans-serif, system-ui, sans-serif', 'fontSize': '15px', 'primaryColor': '#eef2ff', 'primaryTextColor': '#0f172a', 'primaryBorderColor': '#4338ca', 'secondaryColor': '#f8fafc', 'secondaryTextColor': '#334155', 'secondaryBorderColor': '#94a3b8', 'tertiaryColor': '#ffffff', 'tertiaryTextColor': '#1e293b', 'tertiaryBorderColor': '#cbd5e1', 'lineColor': '#64748b', 'textColor': '#0f172a', 'mainBkg': '#ffffff', 'nodeBorder': '#6366f1', 'clusterBkg': '#f8fafc', 'clusterBorder': '#cbd5e1', 'titleColor': '#0f172a', 'edgeLabelBackground': '#ffffff', 'nodeTextColor': '#1e293b', 'actorBkg': '#eef2ff', 'actorBorder': '#4338ca', 'actorTextColor': '#0f172a', 'signalColor': '#64748b', 'labelBoxBkgColor': '#eef2ff', 'labelBoxBorderColor': '#4338ca', 'labelTextColor': '#0f172a', 'loopTextColor': '#475569', 'noteBkgColor': '#fffbeb', 'noteBorderColor': '#d97706', 'noteTextColor': '#78350f' }, 'flowchart': { 'htmlLabels': true, 'curve': 'basis', 'padding': 18, 'nodeSpacing': 55, 'rankSpacing': 65, 'diagramPadding': 24, 'useMaxWidth': true }, 'sequence': { 'actorMargin': 60, 'boxMargin': 12, 'messageMargin': 40, 'mirrorActors': false, 'useMaxWidth': true }, 'state': { 'useMaxWidth': true }}}%%
flowchart LR
OPEN["Open with the client problem<br/>slow, inconsistent brand review"]
subgraph Rubric["Technical leadership arc"]
ROLE["My role<br/>technical lead + builder"]
DEPTH["Technical depth<br/>Figma document tree, retrieval, MCP"]
TRADEOFFS["Tradeoffs<br/>style transfer vs. constraint retrieval"]
INFLUENCE["Influence<br/>brand, engineering, vendor strategy"]
IMPACT["Impact<br/>Frontify, Adobe complementarity, handoff"]
end
OPEN --> ROLE
OPEN --> DEPTH
OPEN --> TRADEOFFS
OPEN --> INFLUENCE
OPEN --> IMPACT
ROLE --> STORY["Core story<br/>I turned an ambiguous AI ask into<br/>a working reference architecture and a clearer strategic direction"]
DEPTH --> STORY
TRADEOFFS --> STORY
INFLUENCE --> STORY
IMPACT --> STORY
class OPEN insight
class ROLE,DEPTH,TRADEOFFS,INFLUENCE,IMPACT highlight
class STORY contract
classDef fail fill:#fef2f2,stroke:#dc2626,stroke-width:2px,color:#991b1b
classDef warn fill:#fffbeb,stroke:#d97706,stroke-width:2px,color:#92400e
classDef ok fill:#ecfdf5,stroke:#059669,stroke-width:2px,color:#065f46
classDef highlight fill:#eff6ff,stroke:#2563eb,stroke-width:2px,color:#1e40af
classDef contract fill:#f0fdf4,stroke:#16a34a,stroke-width:2px,color:#166534
classDef insight fill:#faf5ff,stroke:#9333ea,stroke-width:2px,color:#6b21a8
classDef datastore fill:#f5f3ff,stroke:#7c3aed,stroke-width:2px,color:#5b21b6
classDef muted fill:#f8fafc,stroke:#94a3b8,stroke-width:1px,color:#475569
classDef decision fill:#fff7ed,stroke:#ea580c,stroke-width:2px,color:#9a3412
This section narrows the engagement to two use cases: reviewing agency work and helping designers explore concepts faster. Both needed the same thing underneath: structured access to brand rules.
%%{init: {'theme': 'base', 'themeVariables': { 'fontFamily': '"IBM Plex Sans", ui-sans-serif, system-ui, sans-serif', 'fontSize': '15px', 'primaryColor': '#eef2ff', 'primaryTextColor': '#0f172a', 'primaryBorderColor': '#4338ca', 'secondaryColor': '#f8fafc', 'secondaryTextColor': '#334155', 'secondaryBorderColor': '#94a3b8', 'tertiaryColor': '#ffffff', 'tertiaryTextColor': '#1e293b', 'tertiaryBorderColor': '#cbd5e1', 'lineColor': '#64748b', 'textColor': '#0f172a', 'mainBkg': '#ffffff', 'nodeBorder': '#6366f1', 'clusterBkg': '#f8fafc', 'clusterBorder': '#cbd5e1', 'titleColor': '#0f172a', 'edgeLabelBackground': '#ffffff', 'nodeTextColor': '#1e293b', 'actorBkg': '#eef2ff', 'actorBorder': '#4338ca', 'actorTextColor': '#0f172a', 'signalColor': '#64748b', 'labelBoxBkgColor': '#eef2ff', 'labelBoxBorderColor': '#4338ca', 'labelTextColor': '#0f172a', 'loopTextColor': '#475569', 'noteBkgColor': '#fffbeb', 'noteBorderColor': '#d97706', 'noteTextColor': '#78350f' }, 'flowchart': { 'htmlLabels': true, 'curve': 'basis', 'padding': 18, 'nodeSpacing': 55, 'rankSpacing': 65, 'diagramPadding': 24, 'useMaxWidth': true }, 'sequence': { 'actorMargin': 60, 'boxMargin': 12, 'messageMargin': 40, 'mirrorActors': false, 'useMaxWidth': true }, 'state': { 'useMaxWidth': true }}}%%
flowchart TB
subgraph Presented["What was presented"]
GUIDE["Payments brand kit in Figma<br/>strategy · color · typography · layout · application"]
REVIEWERS["Manual brand reviewers<br/>slow and inconsistent checks"]
DESIGNERS["Internal designers<br/>days to weeks of early iteration"]
end
subgraph Asks["The asks"]
A1["Can AI enforce brand guidelines?<br/>Primary: review agency submissions"]
A2["Can AI accelerate design iterations?<br/>Bonus: generate concepts that follow rules"]
end
subgraph Reframe["Technical reframe"]
I["Brand grounding = constraint problem<br/>not just style transfer"]
R["Need: searchable, structured access<br/>to documented brand rules"]
end
subgraph Foundation["One foundation, two workflows"]
F["Figma document-tree ingestion<br/>semantic chunking<br/>retrieval + citations"]
E["Evaluative mode<br/>Does this conform?"]
G["Generative mode<br/>Produce something that conforms"]
end
GUIDE --> A1
REVIEWERS --> A1
GUIDE --> A2
DESIGNERS --> A2
A1 --> I
A2 --> I
I --> R
R --> F
F --> E
F --> G
class A1,A2 highlight
class I,R insight
class F contract
class E,G ok
classDef fail fill:#fef2f2,stroke:#dc2626,stroke-width:2px,color:#991b1b
classDef warn fill:#fffbeb,stroke:#d97706,stroke-width:2px,color:#92400e
classDef ok fill:#ecfdf5,stroke:#059669,stroke-width:2px,color:#065f46
classDef highlight fill:#eff6ff,stroke:#2563eb,stroke-width:2px,color:#1e40af
classDef contract fill:#f0fdf4,stroke:#16a34a,stroke-width:2px,color:#166534
classDef insight fill:#faf5ff,stroke:#9333ea,stroke-width:2px,color:#6b21a8
classDef datastore fill:#f5f3ff,stroke:#7c3aed,stroke-width:2px,color:#5b21b6
classDef muted fill:#f8fafc,stroke:#94a3b8,stroke-width:1px,color:#475569
classDef decision fill:#fff7ed,stroke:#ea580c,stroke-width:2px,color:#9a3412
linkStyle 6 stroke:#9333ea,stroke-width:2px
This section covers the first two generation attempts. They were useful because they showed that screenshots and style transfer could get close visually, but they could not reliably follow specific brand rules.
%%{init: {'theme': 'base', 'themeVariables': { 'fontFamily': '"IBM Plex Sans", ui-sans-serif, system-ui, sans-serif', 'fontSize': '15px', 'primaryColor': '#eef2ff', 'primaryTextColor': '#0f172a', 'primaryBorderColor': '#4338ca', 'secondaryColor': '#f8fafc', 'secondaryTextColor': '#334155', 'secondaryBorderColor': '#94a3b8', 'tertiaryColor': '#ffffff', 'tertiaryTextColor': '#1e293b', 'tertiaryBorderColor': '#cbd5e1', 'lineColor': '#64748b', 'textColor': '#0f172a', 'mainBkg': '#ffffff', 'nodeBorder': '#6366f1', 'clusterBkg': '#f8fafc', 'clusterBorder': '#cbd5e1', 'titleColor': '#0f172a', 'edgeLabelBackground': '#ffffff', 'nodeTextColor': '#1e293b', 'actorBkg': '#eef2ff', 'actorBorder': '#4338ca', 'actorTextColor': '#0f172a', 'signalColor': '#64748b', 'labelBoxBkgColor': '#eef2ff', 'labelBoxBorderColor': '#4338ca', 'labelTextColor': '#0f172a', 'loopTextColor': '#475569', 'noteBkgColor': '#fffbeb', 'noteBorderColor': '#d97706', 'noteTextColor': '#78350f' }, 'flowchart': { 'htmlLabels': true, 'curve': 'basis', 'padding': 18, 'nodeSpacing': 55, 'rankSpacing': 65, 'diagramPadding': 24, 'useMaxWidth': true }, 'sequence': { 'actorMargin': 60, 'boxMargin': 12, 'messageMargin': 40, 'mirrorActors': false, 'useMaxWidth': true }, 'state': { 'useMaxWidth': true }}}%%
flowchart LR
subgraph Attempt1["Attempt 1 · Foundation models"]
A1["Feed Figma screenshots / PNG exports<br/>into ChatGPT, Nano Banana, etc."]
R1["Result: generic financial-services look<br/>No payments vs. private banking grounding"]
end
subgraph Attempt2["Attempt 2 · LoRA on Replicate"]
A2["Train LoRA on Figma image exports<br/>Style transfer via diffusion fine-tuning"]
R2["Result: ~on-brand aesthetic<br/>Wrong hex codes, logo placement, typography"]
end
subgraph Pivot["Pivot"]
P["Takeaway: style ≠ constraints<br/>→ retrieve the actual brand rules"]
end
A1 --> R1
R1 --> A2
A2 --> R2
R2 --> P
class R1 fail
class R2 warn
class P ok
classDef fail fill:#fef2f2,stroke:#dc2626,stroke-width:2px,color:#991b1b
classDef warn fill:#fffbeb,stroke:#d97706,stroke-width:2px,color:#92400e
classDef ok fill:#ecfdf5,stroke:#059669,stroke-width:2px,color:#065f46
classDef highlight fill:#eff6ff,stroke:#2563eb,stroke-width:2px,color:#1e40af
classDef contract fill:#f0fdf4,stroke:#16a34a,stroke-width:2px,color:#166534
classDef insight fill:#faf5ff,stroke:#9333ea,stroke-width:2px,color:#6b21a8
classDef datastore fill:#f5f3ff,stroke:#7c3aed,stroke-width:2px,color:#5b21b6
classDef muted fill:#f8fafc,stroke:#94a3b8,stroke-width:1px,color:#475569
classDef decision fill:#fff7ed,stroke:#ea580c,stroke-width:2px,color:#9a3412
linkStyle 0 stroke:#dc2626,stroke-width:2px
linkStyle 3 stroke:#059669,stroke-width:2px
This section compares a few ways to get brand guidance out of Figma and explains why the raw document tree was the only path that kept the useful structure intact.
%%{init: {'theme': 'base', 'themeVariables': { 'fontFamily': '"IBM Plex Sans", ui-sans-serif, system-ui, sans-serif', 'fontSize': '15px', 'primaryColor': '#eef2ff', 'primaryTextColor': '#0f172a', 'primaryBorderColor': '#4338ca', 'secondaryColor': '#f8fafc', 'secondaryTextColor': '#334155', 'secondaryBorderColor': '#94a3b8', 'tertiaryColor': '#ffffff', 'tertiaryTextColor': '#1e293b', 'tertiaryBorderColor': '#cbd5e1', 'lineColor': '#64748b', 'textColor': '#0f172a', 'mainBkg': '#ffffff', 'nodeBorder': '#6366f1', 'clusterBkg': '#f8fafc', 'clusterBorder': '#cbd5e1', 'titleColor': '#0f172a', 'edgeLabelBackground': '#ffffff', 'nodeTextColor': '#1e293b', 'actorBkg': '#eef2ff', 'actorBorder': '#4338ca', 'actorTextColor': '#0f172a', 'signalColor': '#64748b', 'labelBoxBkgColor': '#eef2ff', 'labelBoxBorderColor': '#4338ca', 'labelTextColor': '#0f172a', 'loopTextColor': '#475569', 'noteBkgColor': '#fffbeb', 'noteBorderColor': '#d97706', 'noteTextColor': '#78350f' }, 'flowchart': { 'htmlLabels': true, 'curve': 'basis', 'padding': 18, 'nodeSpacing': 55, 'rankSpacing': 65, 'diagramPadding': 24, 'useMaxWidth': true }, 'sequence': { 'actorMargin': 60, 'boxMargin': 12, 'messageMargin': 40, 'mirrorActors': false, 'useMaxWidth': true }, 'state': { 'useMaxWidth': true }}}%%
flowchart TD
Q["How do we turn brand guidance into structured data?<br/>Source: Figma API (JPMC brand kits)"]
Q --> PDF
Q --> PNG
Q --> SVG
Q --> JSON
PDF["PDF export + PDF-to-text"]
PNG["PNG raster exports"]
SVG["SVG vector exports"]
JSON["Raw Figma document JSON tree"]
PDF --> PDF_FAIL["Failed: lost spatial relationships and groupings<br/>Guidance got flattened"]
PNG --> PNG_FAIL["Failed: just pixels, no structure to retrieve"]
SVG --> SVG_FAIL["Failed: shapes, but not enough design-system context"]
JSON --> JSON_OK["Worked: preserved visual semantics + structural metadata<br/>→ custom Bun/TS document-tree walker"]
JSON_OK --> SDK["Off-the-shelf Figma SDK did not cover the traversal I needed<br/>→ wrote a minimal custom SDK"]
class PDF,PNG,SVG muted
class PDF_FAIL,PNG_FAIL,SVG_FAIL fail
class JSON,JSON_OK,SDK ok
classDef fail fill:#fef2f2,stroke:#dc2626,stroke-width:2px,color:#991b1b
classDef warn fill:#fffbeb,stroke:#d97706,stroke-width:2px,color:#92400e
classDef ok fill:#ecfdf5,stroke:#059669,stroke-width:2px,color:#065f46
classDef highlight fill:#eff6ff,stroke:#2563eb,stroke-width:2px,color:#1e40af
classDef contract fill:#f0fdf4,stroke:#16a34a,stroke-width:2px,color:#166534
classDef insight fill:#faf5ff,stroke:#9333ea,stroke-width:2px,color:#6b21a8
classDef datastore fill:#f5f3ff,stroke:#7c3aed,stroke-width:2px,color:#5b21b6
classDef muted fill:#f8fafc,stroke:#94a3b8,stroke-width:1px,color:#475569
classDef decision fill:#fff7ed,stroke:#ea580c,stroke-width:2px,color:#9a3412
linkStyle 3,4 stroke:#059669,stroke-width:2px
A trimmed example from context/example-brand-ast.json. This is the technical structure behind the Figma file, and it explains why the raw tree was more useful than screenshots, PDFs, or flattened exports.
{
"name": "Encyclopedia JPMC",
"document": {
"id": "0:0",
"name": "Document",
"type": "DOCUMENT",
"children": [
{
"id": "476:1227",
"name": "JPM style guides 2",
"type": "CANVAS",
"children": [
{
"id": "487:14604",
"name": "Payments",
"type": "SECTION",
"childrenCount": 218,
"absoluteBoundingBox": {
"x": -115553.015625,
"y": -24706.748046875,
"width": 38624.71875,
"height": 52166.5703125
},
"children": [
{
"id": "1391:22094",
"name": "0.0 Strategy",
"type": "FRAME",
"absoluteBoundingBox": {
"x": -107193,
"y": -19624.748046875,
"width": 1920,
"height": 1080
}
}
]
}
]
}
]
}
}
This section shows how the ingestion approach changed after the first version produced weak retrieval. The fix was to chunk around meaningful design-tree units, not whole pages.
%%{init: {'theme': 'base', 'themeVariables': { 'fontFamily': '"IBM Plex Sans", ui-sans-serif, system-ui, sans-serif', 'fontSize': '15px', 'primaryColor': '#eef2ff', 'primaryTextColor': '#0f172a', 'primaryBorderColor': '#4338ca', 'secondaryColor': '#f8fafc', 'secondaryTextColor': '#334155', 'secondaryBorderColor': '#94a3b8', 'tertiaryColor': '#ffffff', 'tertiaryTextColor': '#1e293b', 'tertiaryBorderColor': '#cbd5e1', 'lineColor': '#64748b', 'textColor': '#0f172a', 'mainBkg': '#ffffff', 'nodeBorder': '#6366f1', 'clusterBkg': '#f8fafc', 'clusterBorder': '#cbd5e1', 'titleColor': '#0f172a', 'edgeLabelBackground': '#ffffff', 'nodeTextColor': '#1e293b', 'actorBkg': '#eef2ff', 'actorBorder': '#4338ca', 'actorTextColor': '#0f172a', 'signalColor': '#64748b', 'labelBoxBkgColor': '#eef2ff', 'labelBoxBorderColor': '#4338ca', 'labelTextColor': '#0f172a', 'loopTextColor': '#475569', 'noteBkgColor': '#fffbeb', 'noteBorderColor': '#d97706', 'noteTextColor': '#78350f' }, 'flowchart': { 'htmlLabels': true, 'curve': 'basis', 'padding': 18, 'nodeSpacing': 55, 'rankSpacing': 65, 'diagramPadding': 24, 'useMaxWidth': true }, 'sequence': { 'actorMargin': 60, 'boxMargin': 12, 'messageMargin': 40, 'mirrorActors': false, 'useMaxWidth': true }, 'state': { 'useMaxWidth': true }}}%%
flowchart TB
subgraph V1["Attempt 1 · Naive ingestion"]
V1A["Embed raw Figma tree into ChromaDB"]
V1B["Chunk at page level"]
V1C["Poor retrieval — embeddings averaged signal<br/>Chunks misaligned with semantic boundaries"]
end
subgraph Diagnosis["What we learned"]
D["Chunk boundaries needed to follow<br/>meaningful units in the design tree<br/>(a Figma-specific chunking problem)"]
OBS["Observation: brand kit = visual artifacts,<br/>not Figma Components / Component Sets"]
end
subgraph V2["Attempt 2 · Semantic recursive descent"]
V2A["Recurse tree until subtree fits embedding window"]
V2B["Emit subtree as chunk; roll ancestor metadata up"]
V2C["Key on Group nodes as cohesive visual units"]
V2D["Dual storage per chunk:<br/>raw tree JSON + derived metadata<br/>(colors, radii, typography)"]
end
subgraph Ops["Incremental ops (prototype)"]
O1["Cache document tree locally"]
O2["Refresh on Figma last_modified"]
O3["Re-embed changed subtrees in the prototype"]
end
V1A --> V1B --> V1C
V1C --> D
D --> V2A
OBS -.-> D
V2A --> V2B --> V2C --> V2D
V2D --> Ops
class V1C fail
class D,OBS insight
class V2D ok
class O1,O2,O3 muted
classDef fail fill:#fef2f2,stroke:#dc2626,stroke-width:2px,color:#991b1b
classDef warn fill:#fffbeb,stroke:#d97706,stroke-width:2px,color:#92400e
classDef ok fill:#ecfdf5,stroke:#059669,stroke-width:2px,color:#065f46
classDef highlight fill:#eff6ff,stroke:#2563eb,stroke-width:2px,color:#1e40af
classDef contract fill:#f0fdf4,stroke:#16a34a,stroke-width:2px,color:#166534
classDef insight fill:#faf5ff,stroke:#9333ea,stroke-width:2px,color:#6b21a8
classDef datastore fill:#f5f3ff,stroke:#7c3aed,stroke-width:2px,color:#5b21b6
classDef muted fill:#f8fafc,stroke:#94a3b8,stroke-width:1px,color:#475569
classDef decision fill:#fff7ed,stroke:#ea580c,stroke-width:2px,color:#9a3412
linkStyle 2 stroke:#dc2626,stroke-width:2px
linkStyle 6 stroke:#059669,stroke-width:2px
This section explains the unit I used for retrieval: a design-tree subtree, sized for embedding, with parent context, raw JSON, and extracted design properties attached.
%%{init: {'theme': 'base', 'themeVariables': { 'fontFamily': '"IBM Plex Sans", ui-sans-serif, system-ui, sans-serif', 'fontSize': '15px', 'primaryColor': '#eef2ff', 'primaryTextColor': '#0f172a', 'primaryBorderColor': '#4338ca', 'secondaryColor': '#f8fafc', 'secondaryTextColor': '#334155', 'secondaryBorderColor': '#94a3b8', 'tertiaryColor': '#ffffff', 'tertiaryTextColor': '#1e293b', 'tertiaryBorderColor': '#cbd5e1', 'lineColor': '#64748b', 'textColor': '#0f172a', 'mainBkg': '#ffffff', 'nodeBorder': '#6366f1', 'clusterBkg': '#f8fafc', 'clusterBorder': '#cbd5e1', 'titleColor': '#0f172a', 'edgeLabelBackground': '#ffffff', 'nodeTextColor': '#1e293b', 'actorBkg': '#eef2ff', 'actorBorder': '#4338ca', 'actorTextColor': '#0f172a', 'signalColor': '#64748b', 'labelBoxBkgColor': '#eef2ff', 'labelBoxBorderColor': '#4338ca', 'labelTextColor': '#0f172a', 'loopTextColor': '#475569', 'noteBkgColor': '#fffbeb', 'noteBorderColor': '#d97706', 'noteTextColor': '#78350f' }, 'flowchart': { 'htmlLabels': true, 'curve': 'basis', 'padding': 18, 'nodeSpacing': 55, 'rankSpacing': 65, 'diagramPadding': 24, 'useMaxWidth': true }, 'sequence': { 'actorMargin': 60, 'boxMargin': 12, 'messageMargin': 40, 'mirrorActors': false, 'useMaxWidth': true }, 'state': { 'useMaxWidth': true }}}%%
flowchart TD
ROOT["Figma file root"]
ROOT --> WALK["Recursive descent"]
WALK --> FIT{"Subtree fits<br/>embedding window?"}
FIT -->|No| WALK
FIT -->|Yes| EMIT["Emit chunk"]
EMIT --> L1["Layer 1: Raw tree JSON<br/>(can rebuild the subtree)"]
EMIT --> L2["Layer 2: Derived metadata<br/>hex tokens, border radii, typography refs"]
EMIT --> META["Parent-path metadata<br/>(hierarchy as context, no overlap windows)"]
L1 --> STORE["ChromaDB (local)<br/>Default text sentence-transformer on JSON"]
L2 --> STORE
META --> STORE
STORE --> PROD["Production upgrade deferred:<br/>text embeddings on JSON + CLIP on rendered previews"]
class FIT decision
class L1,L2,META highlight
class STORE datastore
class PROD muted
classDef fail fill:#fef2f2,stroke:#dc2626,stroke-width:2px,color:#991b1b
classDef warn fill:#fffbeb,stroke:#d97706,stroke-width:2px,color:#92400e
classDef ok fill:#ecfdf5,stroke:#059669,stroke-width:2px,color:#065f46
classDef highlight fill:#eff6ff,stroke:#2563eb,stroke-width:2px,color:#1e40af
classDef contract fill:#f0fdf4,stroke:#16a34a,stroke-width:2px,color:#166534
classDef insight fill:#faf5ff,stroke:#9333ea,stroke-width:2px,color:#6b21a8
classDef datastore fill:#f5f3ff,stroke:#7c3aed,stroke-width:2px,color:#5b21b6
classDef muted fill:#f8fafc,stroke:#94a3b8,stroke-width:1px,color:#475569
classDef decision fill:#fff7ed,stroke:#ea580c,stroke-width:2px,color:#9a3412
{
"chunkId": "payments-color-primary-palette",
"source": {
"file": "JPMC Payments brand kit",
"nodeId": "1391:25334",
"path": ["Payments", "3.0 Color", "Primary palette"]
},
"rawTree": {
"type": "GROUP",
"name": "Primary palette",
"childrenCount": 8
},
"metadata": {
"colors": ["#005EB8", "#00A3E0", "#FFFFFF"],
"usage": ["primary brand color", "supporting accent", "background"],
"citations": ["figma://node/1391:25334"]
},
"retrievalText": "Payments primary palette: use JPMC blue as the main brand color, cyan as a supporting accent, and white for clean backgrounds."
}
This section shows the reference architecture: Figma as the source of truth, a custom extraction and retrieval layer, MCP as the stable tool interface, and generation/orchestration pieces that could change later.
%%{init: {'theme': 'base', 'themeVariables': { 'fontFamily': '"IBM Plex Sans", ui-sans-serif, system-ui, sans-serif', 'fontSize': '15px', 'primaryColor': '#eef2ff', 'primaryTextColor': '#0f172a', 'primaryBorderColor': '#4338ca', 'secondaryColor': '#f8fafc', 'secondaryTextColor': '#334155', 'secondaryBorderColor': '#94a3b8', 'tertiaryColor': '#ffffff', 'tertiaryTextColor': '#1e293b', 'tertiaryBorderColor': '#cbd5e1', 'lineColor': '#64748b', 'textColor': '#0f172a', 'mainBkg': '#ffffff', 'nodeBorder': '#6366f1', 'clusterBkg': '#f8fafc', 'clusterBorder': '#cbd5e1', 'titleColor': '#0f172a', 'edgeLabelBackground': '#ffffff', 'nodeTextColor': '#1e293b', 'actorBkg': '#eef2ff', 'actorBorder': '#4338ca', 'actorTextColor': '#0f172a', 'signalColor': '#64748b', 'labelBoxBkgColor': '#eef2ff', 'labelBoxBorderColor': '#4338ca', 'labelTextColor': '#0f172a', 'loopTextColor': '#475569', 'noteBkgColor': '#fffbeb', 'noteBorderColor': '#d97706', 'noteTextColor': '#78350f' }, 'flowchart': { 'htmlLabels': true, 'curve': 'basis', 'padding': 18, 'nodeSpacing': 55, 'rankSpacing': 65, 'diagramPadding': 24, 'useMaxWidth': true }, 'sequence': { 'actorMargin': 60, 'boxMargin': 12, 'messageMargin': 40, 'mirrorActors': false, 'useMaxWidth': true }, 'state': { 'useMaxWidth': true }}}%%
flowchart TB
subgraph Input["What enters the system"]
FIGMA["Figma org API<br/>canonical brand kits + agency submissions<br/>same auth boundary, same source of truth"]
end
subgraph Foundation["Extraction foundation"]
EXTRACT["Custom Bun/TypeScript Figma SDK<br/>document-tree walker over sections, frames, groups, text, geometry<br/>semantic recursive chunking + incremental refresh"]
end
subgraph Store["Brand knowledge layer"]
KNOWLEDGE["Each chunk stores two views<br/>raw tree JSON so it can be rebuilt<br/>derived metadata for retrieval: colors, typography, radii, links<br/>ChromaDB prototype vector search"]
end
subgraph Contract["Tool interface"]
MCP["MCP server<br/>search_brand_guidelines<br/>get_figma_citation<br/>analyze_compliance"]
end
subgraph Modes["Two workflows on the same substrate"]
EVAL["Evaluative mode<br/>Does this submission conform?<br/>structured issues + formatted feedback"]
GEN["Generative mode<br/>Assemble brand-grounded brief / prompt<br/>backend remains swappable"]
end
subgraph Evidence["Trust and verification loop"]
TRUST["Figma deep links for verification<br/>MCP retrieval logs for diagnosis<br/>guideline-shaped responses for designers"]
end
subgraph Backend["Swappable backend choice"]
COMFY["ComfyUI prototype<br/>local feasibility validation"]
TBD["Production backend TBD<br/>Adobe Firefly · Flux · internal model"]
end
FIGMA --> EXTRACT --> KNOWLEDGE --> MCP
MCP --> EVAL
MCP --> GEN
MCP --> TRUST
EVAL --> TRUST
GEN -.-> COMFY -.-> TBD
FIGMA -.->|"submission and rule source use the same document-tree path"| EXTRACT
KNOWLEDGE -.->|"raw tree for rebuilding, derived fields for retrieval"| MCP
class MCP contract
class EXTRACT highlight
class KNOWLEDGE datastore
class EVAL,GEN ok
class TRUST decision
class COMFY insight
class TBD muted
classDef fail fill:#fef2f2,stroke:#dc2626,stroke-width:2px,color:#991b1b
classDef warn fill:#fffbeb,stroke:#d97706,stroke-width:2px,color:#92400e
classDef ok fill:#ecfdf5,stroke:#059669,stroke-width:2px,color:#065f46
classDef highlight fill:#eff6ff,stroke:#2563eb,stroke-width:2px,color:#1e40af
classDef contract fill:#f0fdf4,stroke:#16a34a,stroke-width:2px,color:#166534
classDef insight fill:#faf5ff,stroke:#9333ea,stroke-width:2px,color:#6b21a8
classDef datastore fill:#f5f3ff,stroke:#7c3aed,stroke-width:2px,color:#5b21b6
classDef muted fill:#f8fafc,stroke:#94a3b8,stroke-width:1px,color:#475569
classDef decision fill:#fff7ed,stroke:#ea580c,stroke-width:2px,color:#9a3412
This section shows the compliance idea: run the brand kit and the agency submission through the same extraction path, then compare them in the same representation.
%%{init: {'theme': 'base', 'themeVariables': { 'fontFamily': '"IBM Plex Sans", ui-sans-serif, system-ui, sans-serif', 'fontSize': '15px', 'primaryColor': '#eef2ff', 'primaryTextColor': '#0f172a', 'primaryBorderColor': '#4338ca', 'secondaryColor': '#f8fafc', 'secondaryTextColor': '#334155', 'secondaryBorderColor': '#94a3b8', 'tertiaryColor': '#ffffff', 'tertiaryTextColor': '#1e293b', 'tertiaryBorderColor': '#cbd5e1', 'lineColor': '#64748b', 'textColor': '#0f172a', 'mainBkg': '#ffffff', 'nodeBorder': '#6366f1', 'clusterBkg': '#f8fafc', 'clusterBorder': '#cbd5e1', 'titleColor': '#0f172a', 'edgeLabelBackground': '#ffffff', 'nodeTextColor': '#1e293b', 'actorBkg': '#eef2ff', 'actorBorder': '#4338ca', 'actorTextColor': '#0f172a', 'signalColor': '#64748b', 'labelBoxBkgColor': '#eef2ff', 'labelBoxBorderColor': '#4338ca', 'labelTextColor': '#0f172a', 'loopTextColor': '#475569', 'noteBkgColor': '#fffbeb', 'noteBorderColor': '#d97706', 'noteTextColor': '#78350f' }, 'flowchart': { 'htmlLabels': true, 'curve': 'basis', 'padding': 18, 'nodeSpacing': 55, 'rankSpacing': 65, 'diagramPadding': 24, 'useMaxWidth': true }, 'sequence': { 'actorMargin': 60, 'boxMargin': 12, 'messageMargin': 40, 'mirrorActors': false, 'useMaxWidth': true }, 'state': { 'useMaxWidth': true }}}%%
flowchart LR
subgraph Rules["Rule source"]
BK["Canonical brand kit<br/>(Figma file)"]
end
subgraph Artifact["Under review"]
SUB["Agency submission<br/>(Figma file)"]
end
subgraph Pipeline["Same document-tree extraction pipeline"]
W["Document-tree walker"]
end
subgraph Rep["Same representation"]
R1["Brand guidance chunks<br/>+ derived properties"]
R2["Submission properties<br/>+ structure"]
end
subgraph Compare["Compliance analysis tool"]
RET["Retrieve relevant brand guidance"]
DIFF["Compare design properties"]
OUT["Structured issues + formatted feedback<br/>(system prompt defines violation vs. variation)"]
end
subgraph Trust["Trust & audit"]
CITE["Citation tool → Figma deep link<br/>Verify in source of truth"]
end
BK --> W
SUB --> W
W --> R1
W --> R2
R1 --> RET
R2 --> DIFF
RET --> DIFF
DIFF --> OUT
RET --> CITE
ANTI["Typical failure mode avoided:<br/>different representations + fragile translation layer"]
ANTI -.-> Pipeline
class W highlight
class R1,R2 datastore
class OUT ok
class CITE contract
class ANTI fail
classDef fail fill:#fef2f2,stroke:#dc2626,stroke-width:2px,color:#991b1b
classDef warn fill:#fffbeb,stroke:#d97706,stroke-width:2px,color:#92400e
classDef ok fill:#ecfdf5,stroke:#059669,stroke-width:2px,color:#065f46
classDef highlight fill:#eff6ff,stroke:#2563eb,stroke-width:2px,color:#1e40af
classDef contract fill:#f0fdf4,stroke:#16a34a,stroke-width:2px,color:#166534
classDef insight fill:#faf5ff,stroke:#9333ea,stroke-width:2px,color:#6b21a8
classDef datastore fill:#f5f3ff,stroke:#7c3aed,stroke-width:2px,color:#5b21b6
classDef muted fill:#f8fafc,stroke:#94a3b8,stroke-width:1px,color:#475569
classDef decision fill:#fff7ed,stroke:#ea580c,stroke-width:2px,color:#9a3412
This section presents the MCP tools as a designer-facing interface: structured search, Figma citations, and responses shaped like brand guidance instead of raw search results.
%%{init: {'theme': 'base', 'themeVariables': { 'fontFamily': '"IBM Plex Sans", ui-sans-serif, system-ui, sans-serif', 'fontSize': '15px', 'primaryColor': '#eef2ff', 'primaryTextColor': '#0f172a', 'primaryBorderColor': '#4338ca', 'secondaryColor': '#f8fafc', 'secondaryTextColor': '#334155', 'secondaryBorderColor': '#94a3b8', 'tertiaryColor': '#ffffff', 'tertiaryTextColor': '#1e293b', 'tertiaryBorderColor': '#cbd5e1', 'lineColor': '#64748b', 'textColor': '#0f172a', 'mainBkg': '#ffffff', 'nodeBorder': '#6366f1', 'clusterBkg': '#f8fafc', 'clusterBorder': '#cbd5e1', 'titleColor': '#0f172a', 'edgeLabelBackground': '#ffffff', 'nodeTextColor': '#1e293b', 'actorBkg': '#eef2ff', 'actorBorder': '#4338ca', 'actorTextColor': '#0f172a', 'signalColor': '#64748b', 'labelBoxBkgColor': '#eef2ff', 'labelBoxBorderColor': '#4338ca', 'labelTextColor': '#0f172a', 'loopTextColor': '#475569', 'noteBkgColor': '#fffbeb', 'noteBorderColor': '#d97706', 'noteTextColor': '#78350f' }, 'flowchart': { 'htmlLabels': true, 'curve': 'basis', 'padding': 18, 'nodeSpacing': 55, 'rankSpacing': 65, 'diagramPadding': 24, 'useMaxWidth': true }, 'sequence': { 'actorMargin': 60, 'boxMargin': 12, 'messageMargin': 40, 'mirrorActors': false, 'useMaxWidth': true }, 'state': { 'useMaxWidth': true }}}%%
flowchart TD
IFACE["Tool response shape<br/>matches how designers ask questions"]
PRINCIPLE["Start from how designers ask questions,<br/>then shape ingestion around that"]
subgraph Tools["MCP tools"]
SEARCH["Search<br/>Primary palette · secondary palette · typography rules<br/>(not raw search chunks)"]
CITE["Citations<br/>Deep links to Figma nodes"]
COMP["Compliance analysis<br/>same-pipeline comparison + structured feedback"]
end
VIS["Visual layout mirrors brand-guideline documents<br/>Not generic chatbot prose"]
IFACE --> SEARCH
IFACE --> COMP
IFACE --- PRINCIPLE
SEARCH --> CITE
COMP --> VIS
SEARCH --> VIS
class IFACE,PRINCIPLE insight
class SEARCH,COMP highlight
class CITE contract
class VIS ok
classDef fail fill:#fef2f2,stroke:#dc2626,stroke-width:2px,color:#991b1b
classDef warn fill:#fffbeb,stroke:#d97706,stroke-width:2px,color:#92400e
classDef ok fill:#ecfdf5,stroke:#059669,stroke-width:2px,color:#065f46
classDef highlight fill:#eff6ff,stroke:#2563eb,stroke-width:2px,color:#1e40af
classDef contract fill:#f0fdf4,stroke:#16a34a,stroke-width:2px,color:#166534
classDef insight fill:#faf5ff,stroke:#9333ea,stroke-width:2px,color:#6b21a8
classDef datastore fill:#f5f3ff,stroke:#7c3aed,stroke-width:2px,color:#5b21b6
classDef muted fill:#f8fafc,stroke:#94a3b8,stroke-width:1px,color:#475569
classDef decision fill:#fff7ed,stroke:#ea580c,stroke-width:2px,color:#9a3412
This section separates brand Q&A from generation brief assembly. ComfyUI was useful for validating the bonus use case, but the final generation backend did not need to be locked behind MCP.
%%{init: {'theme': 'base', 'themeVariables': { 'fontFamily': '"IBM Plex Sans", ui-sans-serif, system-ui, sans-serif', 'fontSize': '15px', 'primaryColor': '#eef2ff', 'primaryTextColor': '#0f172a', 'primaryBorderColor': '#4338ca', 'secondaryColor': '#f8fafc', 'secondaryTextColor': '#334155', 'secondaryBorderColor': '#94a3b8', 'tertiaryColor': '#ffffff', 'tertiaryTextColor': '#1e293b', 'tertiaryBorderColor': '#cbd5e1', 'lineColor': '#64748b', 'textColor': '#0f172a', 'mainBkg': '#ffffff', 'nodeBorder': '#6366f1', 'clusterBkg': '#f8fafc', 'clusterBorder': '#cbd5e1', 'titleColor': '#0f172a', 'edgeLabelBackground': '#ffffff', 'nodeTextColor': '#1e293b', 'actorBkg': '#eef2ff', 'actorBorder': '#4338ca', 'actorTextColor': '#0f172a', 'signalColor': '#64748b', 'labelBoxBkgColor': '#eef2ff', 'labelBoxBorderColor': '#4338ca', 'labelTextColor': '#0f172a', 'loopTextColor': '#475569', 'noteBkgColor': '#fffbeb', 'noteBorderColor': '#d97706', 'noteTextColor': '#78350f' }, 'flowchart': { 'htmlLabels': true, 'curve': 'basis', 'padding': 18, 'nodeSpacing': 55, 'rankSpacing': 65, 'diagramPadding': 24, 'useMaxWidth': true }, 'sequence': { 'actorMargin': 60, 'boxMargin': 12, 'messageMargin': 40, 'mirrorActors': false, 'useMaxWidth': true }, 'state': { 'useMaxWidth': true }}}%%
sequenceDiagram
participant Designer
participant Claude as Claude Desktop
participant MCP as MCP Server
participant Chroma as ChromaDB / retrieval
participant Comfy as ComfyUI (local)
Note over Designer,Comfy: Mode A — Q&A
Designer->>Claude: "What are our payments brand colors?"
Claude->>MCP: search + cite
MCP->>Chroma: retrieve structured guidance
Chroma-->>MCP: palette + metadata
MCP-->>Claude: templated answer + Figma link
Claude-->>Designer: structured response
Note over Designer,Comfy: Mode B — Brief (manual final step)
Designer->>Claude: "Banner concept using payments guidance"
Claude->>MCP: retrieve brand rules
MCP-->>Claude: assembled generation prompt
Note right of Claude: I ran prompt through ComfyUI
Claude->>Comfy: (out of band) validate feasibility
Comfy-->>Designer: ~on-brand image, specific misses
Note over MCP,Comfy: Scoped out: 3rd MCP tool for end-to-end generation
This section summarizes the three evaluation tracks. They pointed to the same conclusion: the pipeline worked, but some of the brand knowledge only lived in designers' heads.
%%{init: {'theme': 'base', 'themeVariables': { 'fontFamily': '"IBM Plex Sans", ui-sans-serif, system-ui, sans-serif', 'fontSize': '15px', 'primaryColor': '#eef2ff', 'primaryTextColor': '#0f172a', 'primaryBorderColor': '#4338ca', 'secondaryColor': '#f8fafc', 'secondaryTextColor': '#334155', 'secondaryBorderColor': '#94a3b8', 'tertiaryColor': '#ffffff', 'tertiaryTextColor': '#1e293b', 'tertiaryBorderColor': '#cbd5e1', 'lineColor': '#64748b', 'textColor': '#0f172a', 'mainBkg': '#ffffff', 'nodeBorder': '#6366f1', 'clusterBkg': '#f8fafc', 'clusterBorder': '#cbd5e1', 'titleColor': '#0f172a', 'edgeLabelBackground': '#ffffff', 'nodeTextColor': '#1e293b', 'actorBkg': '#eef2ff', 'actorBorder': '#4338ca', 'actorTextColor': '#0f172a', 'signalColor': '#64748b', 'labelBoxBkgColor': '#eef2ff', 'labelBoxBorderColor': '#4338ca', 'labelTextColor': '#0f172a', 'loopTextColor': '#475569', 'noteBkgColor': '#fffbeb', 'noteBorderColor': '#d97706', 'noteTextColor': '#78350f' }, 'flowchart': { 'htmlLabels': true, 'curve': 'basis', 'padding': 18, 'nodeSpacing': 55, 'rankSpacing': 65, 'diagramPadding': 24, 'useMaxWidth': true }, 'sequence': { 'actorMargin': 60, 'boxMargin': 12, 'messageMargin': 40, 'mirrorActors': false, 'useMaxWidth': true }, 'state': { 'useMaxWidth': true }}}%%
flowchart TB
subgraph T1["Track 1 · Knowledge retrieval"]
T1M["Regression suite from Figma ground truth<br/>Primary/secondary palette, radii, typography"]
T1X["Cross-brand generalization<br/>Tune on one kit, query untuned kits"]
T1R["Passed — pipeline correct"]
end
subgraph T2["Track 2 · Compliance review"]
T2M["Qualitative testing with brand team<br/>Real submissions, no labeled test set"]
T2R["Directionally working<br/>Obvious violations caught; edge-case long tail"]
end
subgraph T3["Track 3 · Image generation"]
T3M["Live demo co-investigation"]
T3R["~on-brand but specific misses each time<br/>Trace → guidance missing more often than retrieval was wrong"]
end
subgraph Finding["What the tests showed"]
F["Brand = examples + tacit designer consensus<br/>Not fully documented rules"]
D["MCP server as demo and diagnosis tool<br/>Showed gaps collaboratively in demos"]
end
subgraph Next["What this pointed to next"]
N["Turn tacit knowledge into written rules<br/>(→ Frontify migration)"]
end
T1M --> T1R
T1X --> T1R
T2M --> T2R
T3M --> T3R
T2R --> F
T3R --> F
T1R -.->|"retrieval OK; rules incomplete"| F
F --> D
F --> N
class T1R ok
class T2R,T3R warn
class F insight
class D highlight
class N contract
classDef fail fill:#fef2f2,stroke:#dc2626,stroke-width:2px,color:#991b1b
classDef warn fill:#fffbeb,stroke:#d97706,stroke-width:2px,color:#92400e
classDef ok fill:#ecfdf5,stroke:#059669,stroke-width:2px,color:#065f46
classDef highlight fill:#eff6ff,stroke:#2563eb,stroke-width:2px,color:#1e40af
classDef contract fill:#f0fdf4,stroke:#16a34a,stroke-width:2px,color:#166534
classDef insight fill:#faf5ff,stroke:#9333ea,stroke-width:2px,color:#6b21a8
classDef datastore fill:#f5f3ff,stroke:#7c3aed,stroke-width:2px,color:#5b21b6
classDef muted fill:#f8fafc,stroke:#94a3b8,stroke-width:1px,color:#475569
classDef decision fill:#fff7ed,stroke:#ea580c,stroke-width:2px,color:#9a3412
This section covers the move from flat MCP handlers to Mastra workflows. Once the fetch, walk, chunk, retrieve, and format flow repeated across tools, the extra structure became worth it.
%%{init: {'theme': 'base', 'themeVariables': { 'fontFamily': '"IBM Plex Sans", ui-sans-serif, system-ui, sans-serif', 'fontSize': '15px', 'primaryColor': '#eef2ff', 'primaryTextColor': '#0f172a', 'primaryBorderColor': '#4338ca', 'secondaryColor': '#f8fafc', 'secondaryTextColor': '#334155', 'secondaryBorderColor': '#94a3b8', 'tertiaryColor': '#ffffff', 'tertiaryTextColor': '#1e293b', 'tertiaryBorderColor': '#cbd5e1', 'lineColor': '#64748b', 'textColor': '#0f172a', 'mainBkg': '#ffffff', 'nodeBorder': '#6366f1', 'clusterBkg': '#f8fafc', 'clusterBorder': '#cbd5e1', 'titleColor': '#0f172a', 'edgeLabelBackground': '#ffffff', 'nodeTextColor': '#1e293b', 'actorBkg': '#eef2ff', 'actorBorder': '#4338ca', 'actorTextColor': '#0f172a', 'signalColor': '#64748b', 'labelBoxBkgColor': '#eef2ff', 'labelBoxBorderColor': '#4338ca', 'labelTextColor': '#0f172a', 'loopTextColor': '#475569', 'noteBkgColor': '#fffbeb', 'noteBorderColor': '#d97706', 'noteTextColor': '#78350f' }, 'flowchart': { 'htmlLabels': true, 'curve': 'basis', 'padding': 18, 'nodeSpacing': 55, 'rankSpacing': 65, 'diagramPadding': 24, 'useMaxWidth': true }, 'sequence': { 'actorMargin': 60, 'boxMargin': 12, 'messageMargin': 40, 'mirrorActors': false, 'useMaxWidth': true }, 'state': { 'useMaxWidth': true }}}%%
stateDiagram-v2
[*] --> Phase1: MCP tools in flux
state Phase1 {
[*] --> FlatHandlers
FlatHandlers: Anthropic TS MCP library
FlatHandlers: Flat tool handlers, fast iteration
}
Phase1 --> Decision: Tool surface became clearer
state Decision {
[*] --> CostCheck
CostCheck: Duplicated fetch/walk/chunk/retrieve/format
CostCheck: Ad-hoc orchestration, harder testing
}
Decision --> Phase2: Workflow complexity now worth the framework
state Phase2 {
[*] --> MastraHost
MastraHost: Mastra workflows host orchestration
MastraHost: MCP server = stable external interface
}
Phase2 --> [*]
This section places the work on a six- to eight-week calendar, connecting discovery, experiments, architecture buildout, evaluation demos, and handoff.
%%{init: {'theme': 'base', 'themeVariables': { 'fontFamily': '"IBM Plex Sans", ui-sans-serif, system-ui, sans-serif', 'fontSize': '15px', 'primaryColor': '#eef2ff', 'primaryTextColor': '#0f172a', 'primaryBorderColor': '#4338ca', 'secondaryColor': '#f8fafc', 'secondaryTextColor': '#334155', 'secondaryBorderColor': '#94a3b8', 'tertiaryColor': '#ffffff', 'tertiaryTextColor': '#1e293b', 'tertiaryBorderColor': '#cbd5e1', 'lineColor': '#64748b', 'textColor': '#0f172a', 'mainBkg': '#ffffff', 'nodeBorder': '#6366f1', 'clusterBkg': '#f8fafc', 'clusterBorder': '#cbd5e1', 'titleColor': '#0f172a', 'edgeLabelBackground': '#ffffff', 'nodeTextColor': '#1e293b', 'actorBkg': '#eef2ff', 'actorBorder': '#4338ca', 'actorTextColor': '#0f172a', 'signalColor': '#64748b', 'labelBoxBkgColor': '#eef2ff', 'labelBoxBorderColor': '#4338ca', 'labelTextColor': '#0f172a', 'loopTextColor': '#475569', 'noteBkgColor': '#fffbeb', 'noteBorderColor': '#d97706', 'noteTextColor': '#78350f' }, 'flowchart': { 'htmlLabels': true, 'curve': 'basis', 'padding': 18, 'nodeSpacing': 55, 'rankSpacing': 65, 'diagramPadding': 24, 'useMaxWidth': true }, 'sequence': { 'actorMargin': 60, 'boxMargin': 12, 'messageMargin': 40, 'mirrorActors': false, 'useMaxWidth': true }, 'state': { 'useMaxWidth': true }}}%%
flowchart LR
subgraph Calendar["~6–8 weeks calendar · ~2–3 weeks active engineering"]
direction LR
D1["Discovery sessions"]
D2["Early generation experiments<br/>(2 things we ruled out)"]
D3["Figma export attempts<br/>+ chunking v1 → v2"]
D4["MCP server v1"]
D5["Mastra migration + ComfyUI track"]
D6["Evaluation & demos"]
D7["Handoff: reference implementation"]
end
D1 --> D2 --> D3 --> D4 --> D5 --> D6 --> D7
class D1 muted
class D2 fail
class D3,D4 highlight
class D5 insight
class D6 warn
class D7 ok
classDef fail fill:#fef2f2,stroke:#dc2626,stroke-width:2px,color:#991b1b
classDef warn fill:#fffbeb,stroke:#d97706,stroke-width:2px,color:#92400e
classDef ok fill:#ecfdf5,stroke:#059669,stroke-width:2px,color:#065f46
classDef highlight fill:#eff6ff,stroke:#2563eb,stroke-width:2px,color:#1e40af
classDef contract fill:#f0fdf4,stroke:#16a34a,stroke-width:2px,color:#166534
classDef insight fill:#faf5ff,stroke:#9333ea,stroke-width:2px,color:#6b21a8
classDef datastore fill:#f5f3ff,stroke:#7c3aed,stroke-width:2px,color:#5b21b6
classDef muted fill:#f8fafc,stroke:#94a3b8,stroke-width:1px,color:#475569
classDef decision fill:#fff7ed,stroke:#ea580c,stroke-width:2px,color:#9a3412
linkStyle 0,1,2,3,4,5 stroke:#6366f1,stroke-width:2px
This section shows how scope expanded from one brand kit to three and then five, proving generalization without trying to hard-code all seventy-five kits.
%%{init: {'theme': 'base', 'themeVariables': { 'fontFamily': '"IBM Plex Sans", ui-sans-serif, system-ui, sans-serif', 'fontSize': '15px', 'primaryColor': '#eef2ff', 'primaryTextColor': '#0f172a', 'primaryBorderColor': '#4338ca', 'secondaryColor': '#f8fafc', 'secondaryTextColor': '#334155', 'secondaryBorderColor': '#94a3b8', 'tertiaryColor': '#ffffff', 'tertiaryTextColor': '#1e293b', 'tertiaryBorderColor': '#cbd5e1', 'lineColor': '#64748b', 'textColor': '#0f172a', 'mainBkg': '#ffffff', 'nodeBorder': '#6366f1', 'clusterBkg': '#f8fafc', 'clusterBorder': '#cbd5e1', 'titleColor': '#0f172a', 'edgeLabelBackground': '#ffffff', 'nodeTextColor': '#1e293b', 'actorBkg': '#eef2ff', 'actorBorder': '#4338ca', 'actorTextColor': '#0f172a', 'signalColor': '#64748b', 'labelBoxBkgColor': '#eef2ff', 'labelBoxBorderColor': '#4338ca', 'labelTextColor': '#0f172a', 'loopTextColor': '#475569', 'noteBkgColor': '#fffbeb', 'noteBorderColor': '#d97706', 'noteTextColor': '#78350f' }, 'flowchart': { 'htmlLabels': true, 'curve': 'basis', 'padding': 18, 'nodeSpacing': 55, 'rankSpacing': 65, 'diagramPadding': 24, 'useMaxWidth': true }, 'sequence': { 'actorMargin': 60, 'boxMargin': 12, 'messageMargin': 40, 'mirrorActors': false, 'useMaxWidth': true }, 'state': { 'useMaxWidth': true }}}%%
flowchart LR
subgraph Brands["Brand kit scope"]
B1["1 kit<br/>Deep pipeline development"]
B2["3 kits<br/>Generalization testing"]
B3["5 kits<br/>Handoff baseline"]
B4["75 kits total<br/>Architecture shown generalizable"]
end
B1 --> B2 --> B3 --> B4
class B1 highlight
class B2 insight
class B3 contract
class B4 ok
classDef fail fill:#fef2f2,stroke:#dc2626,stroke-width:2px,color:#991b1b
classDef warn fill:#fffbeb,stroke:#d97706,stroke-width:2px,color:#92400e
classDef ok fill:#ecfdf5,stroke:#059669,stroke-width:2px,color:#065f46
classDef highlight fill:#eff6ff,stroke:#2563eb,stroke-width:2px,color:#1e40af
classDef contract fill:#f0fdf4,stroke:#16a34a,stroke-width:2px,color:#166534
classDef insight fill:#faf5ff,stroke:#9333ea,stroke-width:2px,color:#6b21a8
classDef datastore fill:#f5f3ff,stroke:#7c3aed,stroke-width:2px,color:#5b21b6
classDef muted fill:#f8fafc,stroke:#94a3b8,stroke-width:1px,color:#475569
classDef decision fill:#fff7ed,stroke:#ea580c,stroke-width:2px,color:#9a3412
linkStyle 0,1,2 stroke:#6366f1,stroke-width:2px
This section connects the prototype to client outcomes: the Frontify direction, a clearer Adobe strategy, a reproducible reference implementation, and a sharper diagnosis of the real brand bottleneck.
%%{init: {'theme': 'base', 'themeVariables': { 'fontFamily': '"IBM Plex Sans", ui-sans-serif, system-ui, sans-serif', 'fontSize': '15px', 'primaryColor': '#eef2ff', 'primaryTextColor': '#0f172a', 'primaryBorderColor': '#4338ca', 'secondaryColor': '#f8fafc', 'secondaryTextColor': '#334155', 'secondaryBorderColor': '#94a3b8', 'tertiaryColor': '#ffffff', 'tertiaryTextColor': '#1e293b', 'tertiaryBorderColor': '#cbd5e1', 'lineColor': '#64748b', 'textColor': '#0f172a', 'mainBkg': '#ffffff', 'nodeBorder': '#6366f1', 'clusterBkg': '#f8fafc', 'clusterBorder': '#cbd5e1', 'titleColor': '#0f172a', 'edgeLabelBackground': '#ffffff', 'nodeTextColor': '#1e293b', 'actorBkg': '#eef2ff', 'actorBorder': '#4338ca', 'actorTextColor': '#0f172a', 'signalColor': '#64748b', 'labelBoxBkgColor': '#eef2ff', 'labelBoxBorderColor': '#4338ca', 'labelTextColor': '#0f172a', 'loopTextColor': '#475569', 'noteBkgColor': '#fffbeb', 'noteBorderColor': '#d97706', 'noteTextColor': '#78350f' }, 'flowchart': { 'htmlLabels': true, 'curve': 'basis', 'padding': 18, 'nodeSpacing': 55, 'rankSpacing': 65, 'diagramPadding': 24, 'useMaxWidth': true }, 'sequence': { 'actorMargin': 60, 'boxMargin': 12, 'messageMargin': 40, 'mirrorActors': false, 'useMaxWidth': true }, 'state': { 'useMaxWidth': true }}}%%
flowchart TB
ENG["Feasibility engagement"]
ENG --> O1["Outcome 1: Frontify selected<br/>Turn tacit rules into written brand rules"]
ENG --> O2["Outcome 2: Adobe complementarity<br/>Vendor generation + owned MCP retrieval/compliance"]
ENG --> O3["Outcome 3: Follow-on trust signal<br/>Client confidence in the direction"]
ENG --> DEL["Deliverable: Reference implementation<br/>Repo · findings · how to run it<br/>Chroma · MCP+Mastra · ComfyUI workflow"]
FIND["Diagnostic finding"] --> O1
FIND2["Pipeline correct; rules incomplete"] --> O1
class DEL contract
class O1 highlight
class O2,O3 muted
class FIND,FIND2 insight
classDef fail fill:#fef2f2,stroke:#dc2626,stroke-width:2px,color:#991b1b
classDef warn fill:#fffbeb,stroke:#d97706,stroke-width:2px,color:#92400e
classDef ok fill:#ecfdf5,stroke:#059669,stroke-width:2px,color:#065f46
classDef highlight fill:#eff6ff,stroke:#2563eb,stroke-width:2px,color:#1e40af
classDef contract fill:#f0fdf4,stroke:#16a34a,stroke-width:2px,color:#166534
classDef insight fill:#faf5ff,stroke:#9333ea,stroke-width:2px,color:#6b21a8
classDef datastore fill:#f5f3ff,stroke:#7c3aed,stroke-width:2px,color:#5b21b6
classDef muted fill:#f8fafc,stroke:#94a3b8,stroke-width:1px,color:#475569
classDef decision fill:#fff7ed,stroke:#ea580c,stroke-width:2px,color:#9a3412
This section distills the architecture lesson: keep the interface stable, because retrieval, workflows, generation models, and prompts will keep changing behind it.
%%{init: {'theme': 'base', 'themeVariables': { 'fontFamily': '"IBM Plex Sans", ui-sans-serif, system-ui, sans-serif', 'fontSize': '15px', 'primaryColor': '#eef2ff', 'primaryTextColor': '#0f172a', 'primaryBorderColor': '#4338ca', 'secondaryColor': '#f8fafc', 'secondaryTextColor': '#334155', 'secondaryBorderColor': '#94a3b8', 'tertiaryColor': '#ffffff', 'tertiaryTextColor': '#1e293b', 'tertiaryBorderColor': '#cbd5e1', 'lineColor': '#64748b', 'textColor': '#0f172a', 'mainBkg': '#ffffff', 'nodeBorder': '#6366f1', 'clusterBkg': '#f8fafc', 'clusterBorder': '#cbd5e1', 'titleColor': '#0f172a', 'edgeLabelBackground': '#ffffff', 'nodeTextColor': '#1e293b', 'actorBkg': '#eef2ff', 'actorBorder': '#4338ca', 'actorTextColor': '#0f172a', 'signalColor': '#64748b', 'labelBoxBkgColor': '#eef2ff', 'labelBoxBorderColor': '#4338ca', 'labelTextColor': '#0f172a', 'loopTextColor': '#475569', 'noteBkgColor': '#fffbeb', 'noteBorderColor': '#d97706', 'noteTextColor': '#78350f' }, 'flowchart': { 'htmlLabels': true, 'curve': 'basis', 'padding': 18, 'nodeSpacing': 55, 'rankSpacing': 65, 'diagramPadding': 24, 'useMaxWidth': true }, 'sequence': { 'actorMargin': 60, 'boxMargin': 12, 'messageMargin': 40, 'mirrorActors': false, 'useMaxWidth': true }, 'state': { 'useMaxWidth': true }}}%%
flowchart TB
subgraph Layers["Stable interface / changing implementation at every layer"]
L1["MCP server ↔ Mastra workflows"]
L2["Brand knowledge interface ↔ generation backend"]
L3["Compliance feedback format ↔ system prompt"]
L4["Tool response shape ↔ ingestion + chunking"]
end
LESSON["Whatever sits behind the interface will change<br/>Human craft · retrieval · agent framework · diffusion model<br/>The interface is what needs to last"]
L1 --> LESSON
L2 --> LESSON
L3 --> LESSON
L4 --> LESSON
class L1,L2,L3,L4 highlight
class LESSON contract
classDef fail fill:#fef2f2,stroke:#dc2626,stroke-width:2px,color:#991b1b
classDef warn fill:#fffbeb,stroke:#d97706,stroke-width:2px,color:#92400e
classDef ok fill:#ecfdf5,stroke:#059669,stroke-width:2px,color:#065f46
classDef highlight fill:#eff6ff,stroke:#2563eb,stroke-width:2px,color:#1e40af
classDef contract fill:#f0fdf4,stroke:#16a34a,stroke-width:2px,color:#166534
classDef insight fill:#faf5ff,stroke:#9333ea,stroke-width:2px,color:#6b21a8
classDef datastore fill:#f5f3ff,stroke:#7c3aed,stroke-width:2px,color:#5b21b6
classDef muted fill:#f8fafc,stroke:#94a3b8,stroke-width:1px,color:#475569
classDef decision fill:#fff7ed,stroke:#ea580c,stroke-width:2px,color:#9a3412
This section makes technical ownership explicit: the custom Figma SDK, document-tree walker, chunking algorithm, metadata extraction, MCP tools, evaluation, and handoff materials.
%%{init: {'theme': 'base', 'themeVariables': { 'fontFamily': '"IBM Plex Sans", ui-sans-serif, system-ui, sans-serif', 'fontSize': '15px', 'primaryColor': '#eef2ff', 'primaryTextColor': '#0f172a', 'primaryBorderColor': '#4338ca', 'secondaryColor': '#f8fafc', 'secondaryTextColor': '#334155', 'secondaryBorderColor': '#94a3b8', 'tertiaryColor': '#ffffff', 'tertiaryTextColor': '#1e293b', 'tertiaryBorderColor': '#cbd5e1', 'lineColor': '#64748b', 'textColor': '#0f172a', 'mainBkg': '#ffffff', 'nodeBorder': '#6366f1', 'clusterBkg': '#f8fafc', 'clusterBorder': '#cbd5e1', 'titleColor': '#0f172a', 'edgeLabelBackground': '#ffffff', 'nodeTextColor': '#1e293b', 'actorBkg': '#eef2ff', 'actorBorder': '#4338ca', 'actorTextColor': '#0f172a', 'signalColor': '#64748b', 'labelBoxBkgColor': '#eef2ff', 'labelBoxBorderColor': '#4338ca', 'labelTextColor': '#0f172a', 'loopTextColor': '#475569', 'noteBkgColor': '#fffbeb', 'noteBorderColor': '#d97706', 'noteTextColor': '#78350f' }, 'flowchart': { 'htmlLabels': true, 'curve': 'basis', 'padding': 18, 'nodeSpacing': 55, 'rankSpacing': 65, 'diagramPadding': 24, 'useMaxWidth': true }, 'sequence': { 'actorMargin': 60, 'boxMargin': 12, 'messageMargin': 40, 'mirrorActors': false, 'useMaxWidth': true }, 'state': { 'useMaxWidth': true }}}%%
flowchart TB
ME["My direct contribution<br/>technical lead who personally built the prototype"]
subgraph Built["Code / systems I personally wrote"]
SDK["Minimal Figma SDK<br/>file fetch, traversal, node search, enums"]
WALKER["Document-tree walker + semantic grouping<br/>preserve structure and metadata"]
CHUNKER["Recursive chunking pipeline<br/>raw tree + derived metadata"]
MCP["Custom MCP server<br/>search, citations, compliance analysis"]
EVAL["Retrieval regression suite<br/>known-answer queries + cross-brand tests"]
HANDOFF["Reference implementation<br/>repo, findings, how to run it"]
end
subgraph Integrated["Systems I integrated"]
FIGMA["Figma org API"]
CHROMA["ChromaDB"]
MASTRA["Mastra workflows"]
COMFY["ComfyUI validation track"]
end
ME --> SDK --> WALKER --> CHUNKER --> MCP --> EVAL --> HANDOFF
WALKER --> FIGMA
CHUNKER --> CHROMA
MCP --> MASTRA
MCP -.->|"generation prompt path"| COMFY
class ME insight
class SDK,WALKER,CHUNKER,MCP,EVAL,HANDOFF contract
class FIGMA,CHROMA,MASTRA,COMFY datastore
classDef fail fill:#fef2f2,stroke:#dc2626,stroke-width:2px,color:#991b1b
classDef warn fill:#fffbeb,stroke:#d97706,stroke-width:2px,color:#92400e
classDef ok fill:#ecfdf5,stroke:#059669,stroke-width:2px,color:#065f46
classDef highlight fill:#eff6ff,stroke:#2563eb,stroke-width:2px,color:#1e40af
classDef contract fill:#f0fdf4,stroke:#16a34a,stroke-width:2px,color:#166534
classDef insight fill:#faf5ff,stroke:#9333ea,stroke-width:2px,color:#6b21a8
classDef datastore fill:#f5f3ff,stroke:#7c3aed,stroke-width:2px,color:#5b21b6
classDef muted fill:#f8fafc,stroke:#94a3b8,stroke-width:1px,color:#475569
classDef decision fill:#fff7ed,stroke:#ea580c,stroke-width:2px,color:#9a3412
This section maps how the prototype helped align brand, program, engineering, and vendor-strategy stakeholders by shifting the conversation from model choice to which rules were actually written down.
%%{init: {'theme': 'base', 'themeVariables': { 'fontFamily': '"IBM Plex Sans", ui-sans-serif, system-ui, sans-serif', 'fontSize': '15px', 'primaryColor': '#eef2ff', 'primaryTextColor': '#0f172a', 'primaryBorderColor': '#4338ca', 'secondaryColor': '#f8fafc', 'secondaryTextColor': '#334155', 'secondaryBorderColor': '#94a3b8', 'tertiaryColor': '#ffffff', 'tertiaryTextColor': '#1e293b', 'tertiaryBorderColor': '#cbd5e1', 'lineColor': '#64748b', 'textColor': '#0f172a', 'mainBkg': '#ffffff', 'nodeBorder': '#6366f1', 'clusterBkg': '#f8fafc', 'clusterBorder': '#cbd5e1', 'titleColor': '#0f172a', 'edgeLabelBackground': '#ffffff', 'nodeTextColor': '#1e293b', 'actorBkg': '#eef2ff', 'actorBorder': '#4338ca', 'actorTextColor': '#0f172a', 'signalColor': '#64748b', 'labelBoxBkgColor': '#eef2ff', 'labelBoxBorderColor': '#4338ca', 'labelTextColor': '#0f172a', 'loopTextColor': '#475569', 'noteBkgColor': '#fffbeb', 'noteBorderColor': '#d97706', 'noteTextColor': '#78350f' }, 'flowchart': { 'htmlLabels': true, 'curve': 'basis', 'padding': 18, 'nodeSpacing': 55, 'rankSpacing': 65, 'diagramPadding': 24, 'useMaxWidth': true }, 'sequence': { 'actorMargin': 60, 'boxMargin': 12, 'messageMargin': 40, 'mirrorActors': false, 'useMaxWidth': true }, 'state': { 'useMaxWidth': true }}}%%
flowchart TB
AMBIG["Ambiguous mandate<br/>find meaningful AI uses for brand"]
subgraph Stakeholders["People / groups I worked with"]
BRAND["Head of Brand + brand designers<br/>source of craft knowledge"]
PM["Program manager<br/>scope, cadence, demos"]
ENG["JPMC engineering<br/>future production owner"]
STRAT["Adobe / vendor strategy<br/>avoid blocking owned workflows"]
end
subgraph Moves["Leadership moves"]
LISTEN["Discovery sessions<br/>understand bottlenecks and constraints"]
PROVE["Working instrument<br/>let demos expose real gaps"]
REFRAME["Reframe disagreement<br/>from 'which model?' to 'which rules are written down?'"]
HANDOFF["Reference implementation<br/>make the path reproducible for teams not in the room"]
end
subgraph Shift["Outcome of influence"]
FRONTIFY["Brand-management migration<br/>write down tacit rules"]
ADOBE["Adobe complementarity<br/>vendor generation + owned MCP retrieval"]
TRUST["Trust transferred to source of truth<br/>Figma citations + auditability"]
end
AMBIG --> BRAND
AMBIG --> PM
AMBIG --> ENG
AMBIG --> STRAT
BRAND --> LISTEN --> PROVE --> REFRAME
PM --> PROVE
ENG --> HANDOFF
STRAT --> ADOBE
REFRAME --> FRONTIFY
PROVE --> TRUST
HANDOFF --> TRUST
class AMBIG insight
class LISTEN,PROVE,REFRAME,HANDOFF highlight
class FRONTIFY,ADOBE,TRUST contract
class BRAND,PM,ENG,STRAT muted
classDef fail fill:#fef2f2,stroke:#dc2626,stroke-width:2px,color:#991b1b
classDef warn fill:#fffbeb,stroke:#d97706,stroke-width:2px,color:#92400e
classDef ok fill:#ecfdf5,stroke:#059669,stroke-width:2px,color:#065f46
classDef highlight fill:#eff6ff,stroke:#2563eb,stroke-width:2px,color:#1e40af
classDef contract fill:#f0fdf4,stroke:#16a34a,stroke-width:2px,color:#166534
classDef insight fill:#faf5ff,stroke:#9333ea,stroke-width:2px,color:#6b21a8
classDef datastore fill:#f5f3ff,stroke:#7c3aed,stroke-width:2px,color:#5b21b6
classDef muted fill:#f8fafc,stroke:#94a3b8,stroke-width:1px,color:#475569
classDef decision fill:#fff7ed,stroke:#ea580c,stroke-width:2px,color:#9a3412
This section clarifies MCP's role: it is a strong tool contract for portability, structure, and citations, but orchestration, lifecycle concerns, and generation backends still need separate design decisions.
%%{init: {'theme': 'base', 'themeVariables': { 'fontFamily': '"IBM Plex Sans", ui-sans-serif, system-ui, sans-serif', 'fontSize': '15px', 'primaryColor': '#eef2ff', 'primaryTextColor': '#0f172a', 'primaryBorderColor': '#4338ca', 'secondaryColor': '#f8fafc', 'secondaryTextColor': '#334155', 'secondaryBorderColor': '#94a3b8', 'tertiaryColor': '#ffffff', 'tertiaryTextColor': '#1e293b', 'tertiaryBorderColor': '#cbd5e1', 'lineColor': '#64748b', 'textColor': '#0f172a', 'mainBkg': '#ffffff', 'nodeBorder': '#6366f1', 'clusterBkg': '#f8fafc', 'clusterBorder': '#cbd5e1', 'titleColor': '#0f172a', 'edgeLabelBackground': '#ffffff', 'nodeTextColor': '#1e293b', 'actorBkg': '#eef2ff', 'actorBorder': '#4338ca', 'actorTextColor': '#0f172a', 'signalColor': '#64748b', 'labelBoxBkgColor': '#eef2ff', 'labelBoxBorderColor': '#4338ca', 'labelTextColor': '#0f172a', 'loopTextColor': '#475569', 'noteBkgColor': '#fffbeb', 'noteBorderColor': '#d97706', 'noteTextColor': '#78350f' }, 'flowchart': { 'htmlLabels': true, 'curve': 'basis', 'padding': 18, 'nodeSpacing': 55, 'rankSpacing': 65, 'diagramPadding': 24, 'useMaxWidth': true }, 'sequence': { 'actorMargin': 60, 'boxMargin': 12, 'messageMargin': 40, 'mirrorActors': false, 'useMaxWidth': true }, 'state': { 'useMaxWidth': true }}}%%
flowchart LR
Q["Build decision<br/>What belongs in the MCP contract?"]
subgraph MCPGood["MCP handles well"]
TOOLS["Tool boundary<br/>search, cite, analyze"]
HOSTS["Host portability<br/>Claude Desktop now, other MCP hosts later"]
TRACE["Traceability<br/>structured outputs + Figma citations"]
end
subgraph MCPLimits["MCP does not solve"]
ORCH["Complex orchestration<br/>needs workflow layer"]
STATE["Production state / eval / auth lifecycle<br/>still app concerns"]
GEN["Image generation backend choice<br/>should remain swappable"]
end
subgraph Decisions["Resulting architecture decisions"]
MASTRA["Use Mastra behind MCP<br/>after tool flows stabilized"]
NO_GEN_TOOL["Keep ComfyUI outside MCP<br/>avoid freezing backend choice"]
CONTRACT["Treat MCP as contract<br/>not the whole application"]
end
Q --> TOOLS
Q --> HOSTS
Q --> TRACE
Q --> ORCH
Q --> STATE
Q --> GEN
ORCH --> MASTRA
GEN --> NO_GEN_TOOL
TOOLS --> CONTRACT
HOSTS --> CONTRACT
TRACE --> CONTRACT
class Q insight
class TOOLS,HOSTS,TRACE ok
class ORCH,STATE,GEN warn
class MASTRA,NO_GEN_TOOL,CONTRACT contract
classDef fail fill:#fef2f2,stroke:#dc2626,stroke-width:2px,color:#991b1b
classDef warn fill:#fffbeb,stroke:#d97706,stroke-width:2px,color:#92400e
classDef ok fill:#ecfdf5,stroke:#059669,stroke-width:2px,color:#065f46
classDef highlight fill:#eff6ff,stroke:#2563eb,stroke-width:2px,color:#1e40af
classDef contract fill:#f0fdf4,stroke:#16a34a,stroke-width:2px,color:#166534
classDef insight fill:#faf5ff,stroke:#9333ea,stroke-width:2px,color:#6b21a8
classDef datastore fill:#f5f3ff,stroke:#7c3aed,stroke-width:2px,color:#5b21b6
classDef muted fill:#f8fafc,stroke:#94a3b8,stroke-width:1px,color:#475569
classDef decision fill:#fff7ed,stroke:#ea580c,stroke-width:2px,color:#9a3412