Agentman brand styling for DOCX report generation using python-docx. Use when generating ANY Word document report. Provides mandatory RGBColor constants, table styling functions, paragraph styles, document setup, and a pre-generation checklist. Ensures every DOCX uses the Agentman warm terracotta/charcoal palette instead of Word's default blue/gray styles. Load this skill BEFORE writing any DOCX generation code.
# Agentman DOCX Style Guide
## When to Use
Load this skill **before writing any DOCX generation code** using `python-docx`. This skill provides the complete Agentman brand implementation for Word document output.
**The brand identity is quiet confidence** — charcoal suits, not fire trucks. Carbon and warm neutrals do the heavy lifting. Terracotta appears as a rare, deliberate accent.
## STOP — Read Before Writing Any Code
Before writing a SINGLE line of DOCX generation code, you MUST:
1. **Define ALL RGBColor constants below** as the first lines of your script
2. **Set document author** to `"Agentman Equity Research Assistant"` via `doc.core_properties.author`
3. **Set document title** to `"Agentman — {Report Title}"` via `doc.core_properties.title`
4. **Display author on page 1** immediately after the report title: `"Author: Agentman Equity Research Assistant"`
5. **NEVER let Word default styles bleed through** — override every heading, body text, and table style
6. **NEVER use built-in table styles** like `'Light Grid'`, `'Medium Shading'` — apply colors manually
7. **NEVER use default heading colors** — Word defaults are blue/black, not Agentman charcoal
---
## Visual Weight Distribution
Every report must maintain this ratio:
- **70% Carbon/Charcoal** (`#141413`, `#292322`, `#3D3735`) — the backbone
- **20% Warm Neutrals** (`#F0EEE6`, `#F6EAE6`, `#E3DACC`, `#FAF9F5`, `#FFFFFF`) — warmth without color
- **10% Terracotta Accent** (`#CC785C`, `#D97757`, `#A65945`) — sparingly, max 3 per section
---
## python-docx Implementation
### Color Constants (Copy-Paste This Exactly)
```python
from docx import Document
from docx.shared import Pt, Inches, RGBColor, Cm, Emu
from docx.oxml.ns import qn, nsdecls
from docx.oxml import parse_xml
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.enum.table import WD_TABLE_ALIGNMENT, WD_ALIGN_VERTICAL
# ============================================================
# AGENTMAN BRAND COLORS — python-docx RGBColor Constants
# ============================================================
# Primary Brand (Terracotta) — use sparingly, max 3 per section
AGENTMAN_800 = RGBColor(0x70, 0x3B, 0x2D) # Badge text, deep emphasis (rare)
AGENTMAN_700 = RGBColor(0x8B, 0x4A, 0x38) # Cover accent, metric box values (rare)
AGENTMAN_600 = RGBColor(0xA6, 0x59, 0x45) # Negative emphasis text
AGENTMAN_500 = RGBColor(0xCC, 0x78, 0x5C) # PRIMARY ACCENT — stat numbers, table header text
AGENTMAN_400 = RGBColor(0xD9, 0x77, 0x57) # Highlight/caution text
AGENTMAN_200 = RGBColor(0xE6, 0xA8, 0x90) # Badge borders
AGENTMAN_150 = RGBColor(0xE3, 0xDA, 0xCC) # Table borders, separators
AGENTMAN_100 = RGBColor(0xF6, 0xEA, 0xE6) # Table header fill (light warm tint)
AGENTMAN_75 = RGBColor(0xF0, 0xEE, 0xE6) # Highlight row bg, callout blocks
AGENTMAN_50 = RGBColor(0xFA, 0xF9, 0xF5) # Alternate row bg (cream)
# Text Colors (Charcoal) — 70% of visual weight
CHARCOAL_950 = RGBColor(0x14, 0x14, 0x13) # PRIMARY BODY TEXT
CHARCOAL_900 = RGBColor(0x29, 0x23, 0x22) # Section titles, cover title
CHARCOAL_800 = RGBColor(0x3D, 0x37, 0x35) # Secondary text, subheadings
# Neutral (Slate)
SLATE_700 = RGBColor(0x33, 0x41, 0x55) # Secondary text on light
SLATE_600 = RGBColor(0x47, 0x55, 0x69) # Body text secondary, metric labels
SLATE_500 = RGBColor(0x64, 0x74, 0x8B) # Footer, muted captions
SLATE_400 = RGBColor(0x94, 0xA3, 0xB8) # Descriptions, meta text
# ============================================================
# BANNED — NEVER let these Word defaults through:
# Default blue headings, default black (#000000) text,
# 'Light Grid' / 'Medium Shading' / 'Colorful' table styles,
# Default hyperlink blue (#0563C1)
# ============================================================
```
### Cell Shading Helper (Copy-Paste This Exactly)
```python
def set_cell_shading(cell, hex_color):
"""Apply background shading to a DOCX table cell.
Args:
cell: A python-docx table cell object
hex_color: 6-char hex string without '#' (e.g., 'F6EAE6')
"""
shading_elm = parse_xml(
f'<w:shd {nsdecls("w")} w:fill="{hex_color}" w:val="clear"/>'
)
cell._element.get_or_add_tcPr().append(shading_elm)
def set_cell_border(cell, **kwargs):
"""Set borders on a DOCX table cell.
Usage: set_cell_border(cell, bottom={"sz": 4, "color": "E3DACC", "val": "single"})
"""
tc = cell._element
tcPr = tc.get_or_add_tcPr()
tcBorders = tcPr.find(qn('w:tcBorders'))
if tcBorders is None:
tcBorders = parse_xml(f'<w:tcBorders {nsdecls("w")}/>')
tcPr.append(tcBorders)
for edge, attrs in kwargs.items():
element = tcBorders.find(qn(f'w:{edge}'))
if element is None:
element = parse_xml(f'<w:{edge} {nsdecls("w")}/>')
tcBorders.append(element)
for key, val in attrs.items():
element.set(qn(f'w:{key}'), str(val))
```
### Table Styling (Copy-Paste This Exactly)
```python
def style_agentman_table(table, has_header=True):
"""Apply full Agentman brand styling to a python-docx table.
Args:
table: A python-docx Table object
has_header: Whether the first row is a header (default True)
"""
# Remove any built-in style
table.style = 'Table Grid'
table.alignment = WD_TABLE_ALIGNMENT.CENTER
# Set table-wide border color to warm brand
tbl = table._tbl
tblPr = tbl.tblPr if tbl.tblPr is not None else tbl._add_tblPr()
borders = parse_xml(
f'<w:tblBorders {nsdecls("w")}>'
' <w:top w:val="single" w:sz="4" w:space="0" w:color="E3DACC"/>'
' <w:left w:val="single" w:sz="4" w:space="0" w:color="E3DACC"/>'
' <w:bottom w:val="single" w:sz="4" w:space="0" w:color="E3DACC"/>'
' <w:right w:val="single" w:sz="4" w:space="0" w:color="E3DACC"/>'
' <w:insideH w:val="single" w:sz="4" w:space="0" w:color="E3DACC"/>'
' <w:insideV w:val="single" w:sz="4" w:space="0" w:color="E3DACC"/>'
'</w:tblBorders>'
)
# Remove existing borders if any
existing = tblPr.find(qn('w:tblBorders'))
if existing is not None:
tblPr.remove(existing)
tblPr.append(borders)
for row_idx, row in enumerate(table.rows):
for cell_idx, cell in enumerate(row.cells):
# Vertical alignment
cell.vertical_alignment = WD_ALIGN_VERTICAL.CENTER
if row_idx == 0 and has_header:
# HEADER ROW — light warm fill + terracotta text
set_cell_shading(cell, 'F6EAE6')
for paragraph in cell.paragraphs:
paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER
for run in paragraph.runs:
run.font.color.rgb = AGENTMAN_500
run.font.bold = True
run.font.size = Pt(11)
run.font.name = 'Calibri'
else:
# BODY ROWS — alternating white / cream
if row_idx % 2 == 1:
set_cell_shading(cell, 'FFFFFF')
else:
set_cell_shading(cell, 'FAF9F5')
for paragraph in cell.paragraphs:
if cell_idx == 0:
# First column — bold labels, left-aligned
paragraph.alignment = WD_ALIGN_PARAGRAPH.LEFT
for run in paragraph.runs:
run.font.bold = True
run.font.color.rgb = CHARCOAL_950
run.font.size = Pt(10)
run.font.name = 'Calibri'
else:
# Data columns — center-aligned
paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER
for run in paragraph.runs:
run.font.color.rgb = CHARCOAL_950
run.font.size = Pt(10)
run.font.name = 'Calibri'
```
### Highlight Row Helper
```python
def highlight_table_row(table, row_idx):
"""Apply warm cream highlight to a specific row (for totals, summaries)."""
for cell in table.rows[row_idx].cells:
set_cell_shading(cell, 'F0EEE6') # AGENTMAN_75
```
### Document Setup (Copy-Paste This Exactly)
```python
def create_agentman_doc(report_title):
"""Create a new Agentman-branded DOCX document with metadata."""
doc = Document()
# Set document metadata
doc.core_properties.author = "Agentman Equity Research Assistant"
doc.core_properties.title = f"Agentman — {report_title}"
doc.core_properties.company = "Agentman (Chain of Agents, Inc.)"
# Set default font for the document
style = doc.styles['Normal']
font = style.font
font.name = 'Calibri'
font.size = Pt(11)
font.color.rgb = CHARCOAL_950
# Override heading styles to prevent Word blue defaults
for level in range(1, 5):
heading_style = doc.styles[f'Heading {level}']
heading_style.font.name = 'Calibri'
heading_style.font.color.rgb = CHARCOAL_900
heading_style.font.bold = True
if level == 1:
heading_style.font.size = Pt(24)
elif level == 2:
heading_style.font.size = Pt(18)
elif level == 3:
heading_style.font.size = Pt(14)
elif level == 4:
heading_style.font.size = Pt(12)
# Set narrow margins
for section in doc.sections:
section.top_margin = Inches(0.75)
section.bottom_margin = Inches(0.75)
section.left_margin = Inches(0.75)
section.right_margin = Inches(0.75)
return doc
```
### Page 1 Cover Content (Mandatory)
```python
from datetime import date
def build_cover_page(doc, report_title, date_str=None, subtitle=None):
"""Build the mandatory Agentman cover page content.
The title MUST start with 'Agentman —' and the author line
MUST appear immediately after. This is non-negotiable.
Args:
doc: python-docx Document
report_title: main title (prefixed with "Agentman —")
date_str: date string, defaults to today
subtitle: optional subtitle (e.g. "Stock Comparison Report")
"""
if date_str is None:
date_str = date.today().strftime('%B %d, %Y')
# Title — must start with "Agentman —"
title_para = doc.add_heading(f'Agentman — {report_title}', level=1)
for run in title_para.runs:
run.font.color.rgb = CHARCOAL_900
run.font.name = 'Calibri'
# Subtitle — if provided, uses smaller font with clear spacing
if subtitle:
sub_para = doc.add_paragraph()
run = sub_para.add_run(subtitle)
run.font.color.rgb = SLATE_600
run.font.size = Pt(13)
run.font.name = 'Calibri'
# Author — MUST appear immediately after title, non-negotiable
author_para = doc.add_paragraph()
run = author_para.add_run("Author: Agentman Equity Research Assistant")
run.font.color.rgb = SLATE_600
run.font.size = Pt(11)
run.font.name = 'Calibri'
# Date line
date_para = doc.add_paragraph()
run = date_para.add_run(f"{date_str} | Data Source: Financial Modeling Prep")
run.font.color.rgb = SLATE_600
run.font.size = Pt(11)
run.font.name = 'Calibri'
# Terracotta accent line (horizontal rule)
add_terracotta_rule(doc)
return doc
```
### Section Heading with Terracotta Underline
```python
def add_section_heading(doc, text, level=2):
"""Add a section heading with Agentman charcoal text.
Note: The terracotta underline is added via a bottom border on the paragraph.
"""
heading = doc.add_heading(text, level=level)
for run in heading.runs:
run.font.color.rgb = CHARCOAL_900
run.font.name = 'Calibri'
# Add terracotta bottom border to the heading paragraph
pPr = heading._element.get_or_add_pPr()
pBdr = parse_xml(
f'<w:pBdr {nsdecls("w")}>'
' <w:bottom w:val="single" w:sz="18" w:space="4" w:color="CC785C"/>'
'</w:pBdr>'
)
existing = pPr.find(qn('w:pBdr'))
if existing is not None:
pPr.remove(existing)
pPr.append(pBdr)
return heading
```
### Terracotta Accent Rule
```python
def add_terracotta_rule(doc, thickness='18'):
"""Add a terracotta horizontal rule (accent line) to the document."""
para = doc.add_paragraph()
pPr = para._element.get_or_add_pPr()
pBdr = parse_xml(
f'<w:pBdr {nsdecls("w")}>'
f' <w:bottom w:val="single" w:sz="{thickness}" w:space="1" w:color="CC785C"/>'
'</w:pBdr>'
)
pPr.append(pBdr)
return para
```
### Body Text Helpers
```python
def add_body_text(doc, text):
"""Add a body paragraph with Agentman brand styling."""
para = doc.add_paragraph()
run = para.add_run(text)
run.font.color.rgb = CHARCOAL_950
run.font.size = Pt(11)
run.font.name = 'Calibri'
return para
def add_secondary_text(doc, text):
"""Add secondary/meta text in slate."""
para = doc.add_paragraph()
run = para.add_run(text)
run.font.color.rgb = SLATE_600
run.font.size = Pt(10)
run.font.name = 'Calibri'
return para
def add_emphasis_text(doc, text, emphasis='positive'):
"""Add emphasized text using terracotta family.
emphasis: 'positive' (AGENTMAN_500), 'negative' (AGENTMAN_600),
'highlight' (AGENTMAN_400), 'neutral' (CHARCOAL_950)
"""
para = doc.add_paragraph()
run = para.add_run(text)
run.font.bold = True
run.font.size = Pt(11)
run.font.name = 'Calibri'
if emphasis == 'positive':
run.font.color.rgb = AGENTMAN_500
elif emphasis == 'negative':
run.font.color.rgb = AGENTMAN_600
elif emphasis == 'highlight':
run.font.color.rgb = AGENTMAN_400
else:
run.font.color.rgb = CHARCOAL_950
return para
```
### Stat Block Layout (MANDATORY — Prevents Overlap)
**CRITICAL: Never use stacked paragraphs for stat blocks.** Large stat numbers (28pt+) will overlap their labels and adjacent stats when placed as sequential centered paragraphs. Always use a **table** to contain stat blocks.
```python
def add_stat_row(doc, stat_pairs):
"""Add a row of side-by-side stat blocks using a table to prevent overlap.
Args:
doc: python-docx Document
stat_pairs: list of (value, label) tuples,
e.g. [("$264.35", "AAPL Price"), ("$303.33", "GOOGL Price")]
Returns:
The table object containing the stat blocks.
"""
n = len(stat_pairs)
# 2-row table: row 0 = stat numbers, row 1 = labels
table = doc.add_table(rows=2, cols=n)
table.alignment = WD_TABLE_ALIGNMENT.CENTER
# Remove all borders (invisible table)
tbl = table._tbl
tblPr = tbl.tblPr if tbl.tblPr is not None else tbl._add_tblPr()
borders = parse_xml(
f'<w:tblBorders {nsdecls("w")}>'
' <w:top w:val="none" w:sz="0" w:space="0" w:color="auto"/>'
' <w:left w:val="none" w:sz="0" w:space="0" w:color="auto"/>'
' <w:bottom w:val="none" w:sz="0" w:space="0" w:color="auto"/>'
' <w:right w:val="none" w:sz="0" w:space="0" w:color="auto"/>'
' <w:insideH w:val="none" w:sz="0" w:space="0" w:color="auto"/>'
' <w:insideV w:val="none" w:sz="0" w:space="0" w:color="auto"/>'
'</w:tblBorders>'
)
existing = tblPr.find(qn('w:tblBorders'))
if existing is not None:
tblPr.remove(existing)
tblPr.append(borders)
for i, (value, label) in enumerate(stat_pairs):
# Row 0: large terracotta stat number
cell_num = table.rows[0].cells[i]
p = cell_num.paragraphs[0]
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = p.add_run(str(value))
run.font.color.rgb = AGENTMAN_500
run.font.size = Pt(28)
run.font.bold = True
run.font.name = 'Calibri'
# Row 1: small slate label
cell_lbl = table.rows[1].cells[i]
p2 = cell_lbl.paragraphs[0]
p2.alignment = WD_ALIGN_PARAGRAPH.CENTER
run2 = p2.add_run(label)
run2.font.color.rgb = SLATE_600
run2.font.size = Pt(10)
run2.font.name = 'Calibri'
return table
# Usage — ALWAYS use add_stat_row for stat blocks:
# add_stat_row(doc, [("$264.35", "AAPL Price"), ("$303.33", "GOOGL Price")])
# add_stat_row(doc, [("$3.89T", "AAPL Market Cap"), ("$3.67T", "GOOGL Market Cap")])
#
# WRONG (causes overlap — NEVER do this):
# add_stat_block(doc, "$264.35", "AAPL Price")
# add_stat_block(doc, "$303.33", "GOOGL Price")
```
### Callout Block Helper
```python
def add_callout_block(doc, heading_text, body_text):
"""Add an Agentman callout block (warm cream background)."""
# Create a 1x1 table to simulate a callout box
table = doc.add_table(rows=1, cols=1)
cell = table.rows[0].cells[0]
set_cell_shading(cell, 'F0EEE6') # AGENTMAN_75
# Heading in callout
para = cell.paragraphs[0]
run = para.add_run(heading_text)
run.font.color.rgb = CHARCOAL_950
run.font.bold = True
run.font.size = Pt(12)
run.font.name = 'Calibri'
# Body in callout
para2 = cell.add_paragraph()
run2 = para2.add_run(body_text)
run2.font.color.rgb = SLATE_600
run2.font.size = Pt(10)
run2.font.name = 'Calibri'
# Style the table borders
set_cell_border(cell,
top={"sz": 4, "color": "E3DACC", "val": "single"},
bottom={"sz": 4, "color": "E3DACC", "val": "single"},
left={"sz": 4, "color": "E3DACC", "val": "single"},
right={"sz": 4, "color": "E3DACC", "val": "single"})
return table
```
### Badge Helper
```python
def add_badge(paragraph, text):
"""Add an inline badge to an existing paragraph.
All badges use the same Agentman brand colors regardless of tier.
Tier differentiation is via text wording, not color.
"""
run = paragraph.add_run(f" {text} ")
run.font.color.rgb = AGENTMAN_800
run.font.size = Pt(10)
run.font.bold = True
run.font.name = 'Calibri'
# Note: python-docx doesn't natively support inline backgrounds,
# so badges are best implemented as small 1-cell tables or via
# run highlighting with set_cell_shading on a table cell.
return run
```
### Footer Setup
```python
from docx.oxml import parse_xml
from docx.oxml.ns import nsdecls
def add_footer(doc, date_str=None):
"""Add Agentman footer to all pages."""
from datetime import date as dt
if date_str is None:
date_str = dt.today().strftime('%B %d, %Y')
for section in doc.sections:
footer = section.footer
footer.is_linked_to_previous = False
para = footer.paragraphs[0] if footer.paragraphs else footer.add_paragraph()
para.alignment = WD_ALIGN_PARAGRAPH.CENTER
# Terracotta rule above footer
pPr = para._element.get_or_add_pPr()
pBdr = parse_xml(
f'<w:pBdr {nsdecls("w")}>'
' <w:top w:val="single" w:sz="6" w:space="4" w:color="CC785C"/>'
'</w:pBdr>'
)
pPr.append(pBdr)
run = para.add_run(f"Agentman Equity Research Assistant · {date_str} · Data: FMP")
run.font.color.rgb = SLATE_500
run.font.size = Pt(8)
run.font.name = 'Calibri'
```
### Disclaimer
```python
def add_disclaimer(doc):
"""Add the mandatory Agentman disclaimer at the end of the report."""
doc.add_paragraph() # spacer
add_terracotta_rule(doc, thickness='6')
para = doc.add_paragraph()
para.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = para.add_run(
"This Agentman research report is for informational purposes only "
"and does not constitute personalized investment advice. Past performance "
"does not guarantee future results. Investors should conduct their own "
"due diligence and consult a licensed financial advisor. "
"Prepared by Agentman Equity Research Assistant."
)
run.font.color.rgb = SLATE_500
run.font.size = Pt(8)
run.font.italic = True
run.font.name = 'Calibri'
return para
```
---
## Element-to-Color Quick Reference
| Report Element | python-docx Implementation | Color |
|---|---|---|
| Table header fill | `set_cell_shading(cell, 'F6EAE6')` | AGENTMAN_100 |
| Table header text | `run.font.color.rgb = AGENTMAN_500` | #CC785C |
| Table borders | Warm borders via `tblBorders` with `E3DACC` | AGENTMAN_150 |
| Section titles | `run.font.color.rgb = CHARCOAL_900` + bottom border | #292322 |
| Body text | `run.font.color.rgb = CHARCOAL_950` | #141413 |
| Secondary text | `run.font.color.rgb = SLATE_600` | #475569 |
| Footer text | `run.font.color.rgb = SLATE_500` | #64748B |
| Alternate row bg | `set_cell_shading(cell, 'FAF9F5')` | AGENTMAN_50 |
| Highlight row bg | `set_cell_shading(cell, 'F0EEE6')` | AGENTMAN_75 |
| Positive emphasis | `run.font.color.rgb = AGENTMAN_500; run.font.bold = True` | #CC785C |
| Negative emphasis | `run.font.color.rgb = AGENTMAN_600; run.font.bold = True` | #A65945 |
| Badges | `set_cell_shading(cell, 'F6EAE6')` + `AGENTMAN_800` text | #F6EAE6 bg + #703B2D text |
| Document metadata | `doc.core_properties.author` / `.title` | N/A |
---
## Word Default Overrides
These Word defaults MUST be overridden — they will bleed through if not explicitly styled:
| Default | What It Does | Agentman Override |
|---|---|---|
| `Heading 1` style | Blue/black heading | `CHARCOAL_900` (#292322) |
| `Heading 2` style | Blue heading | `CHARCOAL_900` (#292322) |
| Hyperlink style | Blue underline (#0563C1) | `AGENTMAN_500` (#CC785C), no underline |
| Table Style "Light Grid" | Blue-gray grid | Custom brand via `style_agentman_table()` |
| Table Style "Grid" | Black borders | `AGENTMAN_150` (#E3DACC) borders |
| Default body text | Pure black (#000000) | `CHARCOAL_950` (#141413) |
| Default bullet color | Pure black | `CHARCOAL_950` (#141413) |
---
## Banned Colors
| Color | Hex | Why Banned |
|---|---|---|
| Green (success) | #10B981 | Traffic-light aesthetic (except ✓ symbol) |
| Amber (warning) | #F59E0B | Dashboard alert feel |
| Red (error) | #EF4444 | Alarm aesthetic (except ✗ symbol) |
| Blue (info) | #3B82F6 | Generic corporate, dilutes brand |
| Navy | #1B3A5C | Corporate default, not Agentman |
| Pure black | #000000 | Use CHARCOAL_950 (#141413) instead |
| Word default blue | #0563C1 | Default hyperlink color |
| Generic grays | #333, #666, #999 | Use brand palette equivalents |
| Any gradient | N/A | Solid fills only |
---
## Overlap Prevention Rules
**Text overlap is the #1 layout defect.** Follow these rules strictly:
1. **Stat blocks MUST use `add_stat_row()` table layout.** Never place large stat number paragraphs (28pt) followed by small label paragraphs (10pt) as sequential centered paragraphs — they will overlap. Always wrap stat pairs in a table.
2. **Side-by-side content MUST use a table.** Centered paragraphs stack vertically, not horizontally. For side-by-side stat blocks, comparison columns, or any multi-column layout, use a table with invisible borders.
3. **Title + subtitle need separate elements.** Use `build_cover_page(doc, title, subtitle=...)` — never concatenate title and subtitle into one heading.
4. **Add spacing between unrelated blocks.** Insert `doc.add_paragraph()` (empty paragraph) between major sections for breathing room.
---
## Pre-Generation Checklist
Before executing ANY DOCX generation code, verify:
- [ ] **No text overlap** — Stat blocks use `add_stat_row()` table layout, title/subtitle are separate elements with adequate spacing
- [ ] **Color constants defined** — ALL RGBColor constants are in the script
- [ ] **No Word defaults** — Heading styles, table styles, body text all overridden
- [ ] **Document author set** — `doc.core_properties.author = "Agentman Equity Research Assistant"`
- [ ] **Document title set** — `doc.core_properties.title = "Agentman — {Report Title}"`
- [ ] **Page 1 author line** — "Author: Agentman Equity Research Assistant" displayed before data
- [ ] **Title starts with "Agentman —"**
- [ ] **Table headers are LIGHT** — `set_cell_shading(cell, 'F6EAE6')` fill + `AGENTMAN_500` text
- [ ] **No dark table headers** — No navy, dark brown, charcoal, or any saturated fill on headers
- [ ] **No banned colors** — No green, red, amber, blue, navy, or generic grays
- [ ] **Warm borders** — `E3DACC` borders, not black/gray
- [ ] **Alternating rows** — White / `FAF9F5` cream
- [ ] **Terracotta budget** — Max 3 `AGENTMAN_500` elements per section
- [ ] **Footer on every page** — "Agentman Equity Research Assistant · {date} · Data: FMP"
- [ ] **Font is Calibri** — Set on every run, not just the default style
- [ ] **No shadows, gradients, or transparency** — Solid fills only
- [ ] **Visual weight feels 70/20/10** — Mostly charcoal, some cream, rare terracotta
Agentman brand styling for PDF report generation. Use when generating ANY PDF report using reportlab, fpdf2, or weasyprint. Provides mandatory color constants, table styles, document setup, typography, page layout, and a pre-generation checklist. Ensures every PDF uses the Agentman warm terracotta/charcoal palette instead of generic library defaults. Load this skill BEFORE writing any PDF generation code.
PPTX-specific implementation reference for creating Agentman-branded presentations using pptxgenjs. Use when building any PowerPoint deck for Agentman or its clients. Provides slide layouts, typography mapping, card patterns, icon rendering, graphic generation prompts, and narrative structure specific to the presentation format. Requires agentman-styleguide as the canonical source for colors, voice/tone, and brand principles.
Try it now in your favorite AI, or set up MCP for persistent access.
Try Now
Or Set Up MCP