---
name: meridian-ops-review
description: Meridian Capital Partners Monthly Operations Review template. Use when creating monthly ops review decks with financial overview, portfolio operations, team & compliance, and strategic initiatives sections.
---

# Meridian Capital Partners — Monthly Ops Review Template

Template: `assets/template.pptx` (13.33" x 7.50", widescreen 16:9)

Brand colors: Navy `#0A1F44` (primary), Dark Blue `#143C6E` (accent).

## Creating Presentations

```python
from pptx import Presentation
from pptx.util import Inches, Pt, Emu
from pptx.enum.text import PP_ALIGN

prs = Presentation("path/to/skill/assets/template.pptx")

# DELETE all existing slides first
while len(prs.slides) > 0:
    rId = prs.slides._sldIdLst[0].rId
    prs.part.drop_rel(rId)
    del prs.slides._sldIdLst[0]

# Add slides from layouts
slide = prs.slides.add_slide(prs.slide_layouts[LAYOUT_IDX])
```

## Key Layouts

| Index | Name             | Use For                                                    |
|-------|------------------|------------------------------------------------------------|
| 0     | Cover Slide      | Title page — company name, meeting title, date             |
| 1     | Content          | Standard body slides — title, description, bullets, footer |
| 2     | Section Divider  | Section breaks (Financial, Operations, Strategic, etc.)    |
| 3     | Two Column       | Side-by-side comparisons (e.g., plan vs. actual)           |
| 5     | Title Only       | Custom charts/tables — only title + description + footer   |

## Placeholder Mapping

### Layout 0: Cover Slide

| idx | Type             | Position                                      | Use                          |
|-----|------------------|-----------------------------------------------|------------------------------|
| 0   | CENTER_TITLE (3) | x=1.50", y=2.80", w=10.33", h=1.20"          | Company name / main title    |
| 1   | SUBTITLE (4)     | x=1.50", y=4.10", w=10.33", h=0.80"          | Meeting title and date       |
| 10  | DATE (16)        | x=0.50", y=6.95"                              | Date field                   |
| 11  | FOOTER (15)      | x=3.42", y=6.95"                              | Footer text                  |
| 12  | SLIDE_NUMBER (13)| x=7.17", y=6.95"                              | Page number                  |

### Layout 1: Content

| idx | Type         | Position                                      | Use                          |
|-----|--------------|-----------------------------------------------|------------------------------|
| 0   | TITLE (1)    | x=0.75", y=0.42", w=11.83", h=0.60"          | Slide title                  |
| 13  | BODY (2)     | x=0.75", y=1.18", w=11.83", h=0.40"          | Description / subtitle line  |
| 1   | OBJECT (7)   | x=0.75", y=1.90", w=11.83", h=4.72"          | Main body content            |
| 14  | BODY (2)     | x=0.75", y=6.85", w=11.83", h=0.30"          | Footer line                  |
| 15  | BODY (2)     | x=0.75", y=7.05", w=11.83", h=0.25"          | Source / notes               |

### Layout 2: Section Divider

| idx | Type         | Position                                      | Use                          |
|-----|--------------|-----------------------------------------------|------------------------------|
| 0   | TITLE (1)    | x=1.50", y=2.50", w=10.33", h=1.40"          | Section name                 |
| 1   | BODY (2)     | x=1.50", y=4.00", w=10.33", h=0.60"          | Section subtitle / context   |

### Layout 3: Two Column

| idx | Type         | Position                                      | Use                          |
|-----|--------------|-----------------------------------------------|------------------------------|
| 0   | TITLE (1)    | x=0.75", y=0.42", w=11.83", h=0.60"          | Slide title                  |
| 13  | BODY (2)     | x=0.75", y=1.18", w=11.83", h=0.40"          | Description / subtitle line  |
| 1   | OBJECT (7)   | x=0.75", y=1.90", w=5.67", h=4.72"           | Left column content          |
| 2   | OBJECT (7)   | x=6.92", y=1.90", w=5.67", h=4.72"           | Right column content         |
| 14  | BODY (2)     | x=0.75", y=6.85", w=11.83", h=0.30"          | Footer line                  |
| 15  | BODY (2)     | x=0.75", y=7.05", w=11.83", h=0.25"          | Source / notes               |

### Layout 5: Title Only

| idx | Type         | Position                                      | Use                          |
|-----|--------------|-----------------------------------------------|------------------------------|
| 0   | TITLE (1)    | x=0.75", y=0.42", w=11.83", h=0.60"          | Slide title                  |
| 13  | BODY (2)     | x=0.75", y=1.18", w=11.83", h=0.40"          | Description / subtitle line  |
| 14  | BODY (2)     | x=0.75", y=6.85", w=11.83", h=0.30"          | Footer line                  |
| 15  | BODY (2)     | x=0.75", y=7.05", w=11.83", h=0.25"          | Source / notes               |

No OBJECT placeholder — use custom shapes (tables, charts, textboxes) in the content area.

### Content Area Boundaries

```
Content Area (Layouts 1, 3, 5):
- Left margin:  x = 0.75"
- Top (content start): y = 1.90"  (below description line — do NOT place content above this)
- Right edge:   x = 12.58" (0.75 + 11.83)
- Bottom:       y = 6.62"  (above footer at 6.85)
- Full width:   w = 11.83"
- Full height:  h = 4.72"

Two-Column split (Layout 3):
- Left column:   x = 0.75",  w = 5.67"
- Right column:  x = 6.92",  w = 5.67"
- Both columns:  y = 1.90",  h = 4.72"

Title Only custom content area (Layout 5):
- Same boundaries: x=0.75", y=1.90", w=11.83", h=4.72"
- Use this area for manually positioned tables, charts, or textboxes
```

**Why this matters:** Custom content must stay within these boundaries to avoid overlapping with title, description, footer, and source placeholders.

## Filling Placeholders

### Helper: fill a placeholder by idx

```python
def fill_placeholder(slide, idx, text):
    """Set text on a placeholder identified by its idx."""
    for shape in slide.shapes:
        if hasattr(shape, "placeholder_format") and shape.placeholder_format.idx == idx:
            shape.text = text
            return shape
    return None
```

### Helper: fill body content with hierarchy

**Do NOT add manual bullet characters** — the slide master handles bullet formatting.

```python
def fill_body(slide, idx, content):
    """
    Fill an OBJECT or BODY placeholder with hierarchical content.
    content: list of (text, level) tuples.  level 0 = section header, level 1 = bullet.
    """
    for shape in slide.shapes:
        if hasattr(shape, "placeholder_format") and shape.placeholder_format.idx == idx:
            tf = shape.text_frame
            for para in tf.paragraphs:
                para.clear()
            tf.paragraphs[0].text = content[0][0]
            tf.paragraphs[0].level = content[0][1]
            for text, level in content[1:]:
                p = tf.add_paragraph()
                p.text = text
                p.level = level
            return shape
    return None
```

## Standard Monthly Ops Review Structure

The typical deck follows this slide order:

| # | Layout | Title / Purpose |
|---|--------|-----------------|
| 1 | 0 — Cover | "Meridian Capital Partners \| Monthly Operations Review \| [Month Year]" |
| 2 | 2 — Section | "Financial Overview" |
| 3 | 1 — Content | Revenue & margin summary |
| 4 | 3 — Two Column | Plan vs. actual |
| 5 | 2 — Section | "Portfolio Operations" |
| 6 | 1 — Content | AUM and flows |
| 7 | 1 — Content | Client activity |
| 8 | 2 — Section | "Team & Compliance" |
| 9 | 1 — Content | Headcount and hiring |
| 10 | 1 — Content | Compliance and risk items |
| 11 | 2 — Section | "Strategic Initiatives" |
| 12 | 1 or 5 — Content/Title Only | Key projects status |

## Example: Cover Slide

```python
slide = prs.slides.add_slide(prs.slide_layouts[0])
fill_placeholder(slide, 0, "Meridian Capital Partners")
fill_placeholder(slide, 1, "Monthly Operations Review | April 2026")
```

## Example: Section Divider

```python
slide = prs.slides.add_slide(prs.slide_layouts[2])
fill_placeholder(slide, 0, "Financial Overview")
fill_placeholder(slide, 1, "Q1 2026 results and YTD performance")
```

## Example: Content Slide

```python
slide = prs.slides.add_slide(prs.slide_layouts[1])
fill_placeholder(slide, 0, "Revenue & Margin Summary")       # title
fill_placeholder(slide, 13, "Year-over-year comparison")      # description
fill_body(slide, 1, [                                         # main body (OBJECT idx=1)
    ("Revenue", 0),
    ("Total revenue: $12.4M (+18% YoY)", 1),
    ("Management fees: $9.1M (+15% YoY)", 1),
    ("Performance fees: $3.3M (+28% YoY)", 1),
    ("Margins", 0),
    ("Operating margin: 42% (up from 38%)", 1),
    ("EBITDA margin: 48% (up from 44%)", 1),
])
fill_placeholder(slide, 14, "Meridian Capital Partners")      # footer
fill_placeholder(slide, 15, "Source: Internal finance systems") # source
```

## Example: Two-Column Slide (Plan vs. Actual)

```python
slide = prs.slides.add_slide(prs.slide_layouts[3])
fill_placeholder(slide, 0, "Plan vs. Actual — Q1 2026")       # title
fill_placeholder(slide, 13, "Budget comparison")               # description

# Left column — Plan
fill_body(slide, 1, [
    ("Plan", 0),
    ("Revenue target: $11.5M", 1),
    ("New clients: 8", 1),
    ("AUM growth: +5%", 1),
    ("Headcount: 52 FTE", 1),
])

# Right column — Actual
fill_body(slide, 2, [
    ("Actual", 0),
    ("Revenue actual: $12.4M (+8% vs plan)", 1),
    ("New clients: 11", 1),
    ("AUM growth: +7.2%", 1),
    ("Headcount: 54 FTE", 1),
])

fill_placeholder(slide, 14, "Meridian Capital Partners")
fill_placeholder(slide, 15, "Source: Finance & HR systems")
```

## Example: Title Only Slide with Custom Table

Use Layout 5 when you need a manually positioned table or chart.

```python
from pptx.util import Inches, Pt

slide = prs.slides.add_slide(prs.slide_layouts[5])
fill_placeholder(slide, 0, "Key Projects Status")
fill_placeholder(slide, 13, "Strategic initiative tracker")

# Add a table in the content area
rows, cols = 5, 4
left = Inches(0.75)
top = Inches(1.90)
width = Inches(11.83)
height = Inches(3.5)

table_shape = slide.shapes.add_table(rows, cols, left, top, width, height)
table = table_shape.table

# Headers
headers = ["Initiative", "Owner", "Status", "Target Date"]
for i, h in enumerate(headers):
    table.cell(0, i).text = h

# Sample data rows
data = [
    ["Digital onboarding platform", "J. Park", "On Track", "Q2 2026"],
    ["ESG reporting framework", "M. Chen", "At Risk", "Q3 2026"],
    ["Client portal v2", "S. Reyes", "On Track", "Q2 2026"],
    ["Compliance automation", "R. Gupta", "Planning", "Q4 2026"],
]
for r, row_data in enumerate(data, start=1):
    for c, val in enumerate(row_data):
        table.cell(r, c).text = val

fill_placeholder(slide, 14, "Meridian Capital Partners")
fill_placeholder(slide, 15, "Source: PMO tracker")
```

## Full Deck Generation Pattern

```python
from pptx import Presentation
from pptx.util import Inches

prs = Presentation("path/to/skill/assets/template.pptx")

# Delete existing slides
while len(prs.slides) > 0:
    rId = prs.slides._sldIdLst[0].rId
    prs.part.drop_rel(rId)
    del prs.slides._sldIdLst[0]

# --- 1. Cover ---
slide = prs.slides.add_slide(prs.slide_layouts[0])
fill_placeholder(slide, 0, "Meridian Capital Partners")
fill_placeholder(slide, 1, "Monthly Operations Review | [Month Year]")

# --- 2. Section: Financial Overview ---
slide = prs.slides.add_slide(prs.slide_layouts[2])
fill_placeholder(slide, 0, "Financial Overview")
fill_placeholder(slide, 1, "[Period] financial results")

# --- 3. Revenue & Margin Summary ---
slide = prs.slides.add_slide(prs.slide_layouts[1])
fill_placeholder(slide, 0, "Revenue & Margin Summary")
fill_placeholder(slide, 13, "[Period] performance")
fill_body(slide, 1, [
    # Replace with actual data
    ("Revenue", 0),
    ("[Revenue line items]", 1),
    ("Margins", 0),
    ("[Margin line items]", 1),
])
fill_placeholder(slide, 14, "Meridian Capital Partners")
fill_placeholder(slide, 15, "Source: Internal finance systems")

# --- 4. Plan vs. Actual ---
slide = prs.slides.add_slide(prs.slide_layouts[3])
fill_placeholder(slide, 0, "Plan vs. Actual")
fill_placeholder(slide, 13, "[Period] budget comparison")
fill_body(slide, 1, [("Plan", 0), ("[Plan items]", 1)])
fill_body(slide, 2, [("Actual", 0), ("[Actual items]", 1)])
fill_placeholder(slide, 14, "Meridian Capital Partners")
fill_placeholder(slide, 15, "Source: Finance")

# --- 5. Section: Portfolio Operations ---
slide = prs.slides.add_slide(prs.slide_layouts[2])
fill_placeholder(slide, 0, "Portfolio Operations")
fill_placeholder(slide, 1, "AUM, flows, and client activity")

# --- 6. AUM and Flows ---
slide = prs.slides.add_slide(prs.slide_layouts[1])
fill_placeholder(slide, 0, "AUM and Flows")
fill_placeholder(slide, 13, "[Period] summary")
fill_body(slide, 1, [("[AUM data]", 0), ("[Details]", 1)])
fill_placeholder(slide, 14, "Meridian Capital Partners")
fill_placeholder(slide, 15, "Source: Portfolio management system")

# --- 7. Client Activity ---
slide = prs.slides.add_slide(prs.slide_layouts[1])
fill_placeholder(slide, 0, "Client Activity")
fill_placeholder(slide, 13, "[Period] highlights")
fill_body(slide, 1, [("[Client data]", 0), ("[Details]", 1)])
fill_placeholder(slide, 14, "Meridian Capital Partners")
fill_placeholder(slide, 15, "Source: CRM")

# --- 8. Section: Team & Compliance ---
slide = prs.slides.add_slide(prs.slide_layouts[2])
fill_placeholder(slide, 0, "Team & Compliance")
fill_placeholder(slide, 1, "People, hiring, and risk items")

# --- 9. Headcount and Hiring ---
slide = prs.slides.add_slide(prs.slide_layouts[1])
fill_placeholder(slide, 0, "Headcount and Hiring")
fill_placeholder(slide, 13, "[Period] team update")
fill_body(slide, 1, [("[Headcount data]", 0), ("[Details]", 1)])
fill_placeholder(slide, 14, "Meridian Capital Partners")
fill_placeholder(slide, 15, "Source: HR systems")

# --- 10. Compliance and Risk ---
slide = prs.slides.add_slide(prs.slide_layouts[1])
fill_placeholder(slide, 0, "Compliance and Risk Items")
fill_placeholder(slide, 13, "[Period] regulatory and risk update")
fill_body(slide, 1, [("[Compliance items]", 0), ("[Details]", 1)])
fill_placeholder(slide, 14, "Meridian Capital Partners")
fill_placeholder(slide, 15, "Source: Compliance team")

# --- 11. Section: Strategic Initiatives ---
slide = prs.slides.add_slide(prs.slide_layouts[2])
fill_placeholder(slide, 0, "Strategic Initiatives")
fill_placeholder(slide, 1, "Key projects and milestones")

# --- 12. Key Projects Status ---
# Use Layout 5 (Title Only) with a custom table, or Layout 1 with bullets
slide = prs.slides.add_slide(prs.slide_layouts[1])
fill_placeholder(slide, 0, "Key Projects Status")
fill_placeholder(slide, 13, "Initiative tracker")
fill_body(slide, 1, [("[Project statuses]", 0), ("[Details]", 1)])
fill_placeholder(slide, 14, "Meridian Capital Partners")
fill_placeholder(slide, 15, "Source: PMO tracker")

# Save
prs.save("monthly-ops-review-[month]-[year].pptx")
```
