#!/usr/bin/env python3
"""Build the 2026 Digital Agency SOW as a clean, professional Word document."""

from docx import Document
from docx.shared import Pt, Inches, RGBColor, Cm
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.enum.table import WD_TABLE_ALIGNMENT, WD_ALIGN_VERTICAL
from docx.oxml.ns import qn
from docx.oxml import OxmlElement
import copy

# ── Color Palette ──────────────────────────────────────────────────────────────
DARK_NAVY  = RGBColor(0x1A, 0x29, 0x4A)   # headings, header bg
ACCENT     = RGBColor(0x00, 0x7A, 0xC2)   # sub-headings, table header
MID_BLUE   = RGBColor(0xD0, 0xE8, 0xF5)   # table header fill
LIGHT_FILL = RGBColor(0xF2, 0xF7, 0xFB)   # alternating row fill
RULE_COLOR = RGBColor(0x00, 0x7A, 0xC2)   # section rule
WHITE      = RGBColor(0xFF, 0xFF, 0xFF)
BODY_TEXT  = RGBColor(0x1A, 0x1A, 0x2E)
OOS_RED    = RGBColor(0xC0, 0x39, 0x2B)
GREEN_OK   = RGBColor(0x1A, 0x7A, 0x4A)

doc = Document()

# ── Page Setup ─────────────────────────────────────────────────────────────────
section = doc.sections[0]
section.page_width  = Inches(8.5)
section.page_height = Inches(11)
section.top_margin    = Inches(1.0)
section.bottom_margin = Inches(1.0)
section.left_margin   = Inches(1.1)
section.right_margin  = Inches(1.1)

# ── Helpers ────────────────────────────────────────────────────────────────────

def set_cell_bg(cell, hex_color: str):
    """Fill table cell background."""
    tc   = cell._tc
    tcPr = tc.get_or_add_tcPr()
    shd  = OxmlElement('w:shd')
    shd.set(qn('w:val'),   'clear')
    shd.set(qn('w:color'), 'auto')
    shd.set(qn('w:fill'),  hex_color)
    tcPr.append(shd)

def set_cell_borders(cell, color="BBBBBB"):
    tc   = cell._tc
    tcPr = tc.get_or_add_tcPr()
    tcBorders = OxmlElement('w:tcBorders')
    for side in ('top', 'left', 'bottom', 'right'):
        b = OxmlElement(f'w:{side}')
        b.set(qn('w:val'),   'single')
        b.set(qn('w:sz'),    '4')
        b.set(qn('w:space'), '0')
        b.set(qn('w:color'), color)
        tcBorders.append(b)
    # tcBorders must come before w:shd in tcPr schema order
    shd_el = tcPr.find(qn('w:shd'))
    if shd_el is not None:
        tcPr.insert(list(tcPr).index(shd_el), tcBorders)
    else:
        tcPr.append(tcBorders)

def rule(color="007AC2", size=12):
    """Add a thin horizontal rule paragraph."""
    p = doc.add_paragraph()
    p.paragraph_format.space_before = Pt(0)
    p.paragraph_format.space_after  = Pt(4)
    pPr = p._p.get_or_add_pPr()
    pb  = OxmlElement('w:pBdr')
    bot = OxmlElement('w:bottom')
    bot.set(qn('w:val'),   'single')
    bot.set(qn('w:sz'),    str(size))
    bot.set(qn('w:space'), '1')
    bot.set(qn('w:color'), color)
    pb.append(bot)
    # pBdr must come before w:spacing in pPr schema order
    spacing_el = pPr.find(qn('w:spacing'))
    if spacing_el is not None:
        pPr.insert(list(pPr).index(spacing_el), pb)
    else:
        pPr.append(pb)

def add_heading1(text):
    p = doc.add_paragraph()
    p.paragraph_format.space_before = Pt(16)
    p.paragraph_format.space_after  = Pt(2)
    run = p.add_run(text.upper())
    run.bold      = True
    run.font.size = Pt(13)
    run.font.color.rgb = DARK_NAVY
    run.font.name = 'Calibri'
    rule()

def add_heading2(text):
    p = doc.add_paragraph()
    p.paragraph_format.space_before = Pt(10)
    p.paragraph_format.space_after  = Pt(2)
    run = p.add_run(text)
    run.bold      = True
    run.font.size = Pt(11)
    run.font.color.rgb = ACCENT
    run.font.name = 'Calibri'

def add_body(text, bold=False, italic=False, indent=False, color=None):
    p = doc.add_paragraph()
    p.paragraph_format.space_before = Pt(1)
    p.paragraph_format.space_after  = Pt(3)
    if indent:
        p.paragraph_format.left_indent = Inches(0.25)
    run = p.add_run(text)
    run.bold   = bold
    run.italic = italic
    run.font.size  = Pt(10)
    run.font.name  = 'Calibri'
    run.font.color.rgb = color if color else BODY_TEXT

def add_bullet(text, sub=False):
    p = doc.add_paragraph(style='List Bullet')
    p.paragraph_format.space_before = Pt(1)
    p.paragraph_format.space_after  = Pt(2)
    if sub:
        p.paragraph_format.left_indent = Inches(0.5)
    run = p.add_run(text)
    run.font.size = Pt(10)
    run.font.name = 'Calibri'
    run.font.color.rgb = BODY_TEXT

def add_note(text):
    p = doc.add_paragraph()
    p.paragraph_format.space_before = Pt(2)
    p.paragraph_format.space_after  = Pt(4)
    p.paragraph_format.left_indent  = Inches(0.2)
    run = p.add_run(f"ⓘ  {text}")
    run.italic = True
    run.font.size  = Pt(9)
    run.font.name  = 'Calibri'
    run.font.color.rgb = RGBColor(0x55, 0x55, 0x77)

def make_table(headers, rows, col_widths, alt_fill="F2F7FB", header_bg="007AC2"):
    """Create a styled table. col_widths in inches."""
    t = doc.add_table(rows=1 + len(rows), cols=len(headers))
    t.alignment = WD_TABLE_ALIGNMENT.LEFT
    t.style     = 'Table Grid'

    # Header row
    hrow = t.rows[0]
    for i, (h, w) in enumerate(zip(headers, col_widths)):
        cell = hrow.cells[i]
        cell.width = Inches(w)
        set_cell_borders(cell, "007AC2")
        set_cell_bg(cell, header_bg)
        p = cell.paragraphs[0]
        p.paragraph_format.space_before = Pt(3)
        p.paragraph_format.space_after  = Pt(3)
        run = p.add_run(h)
        run.bold = True
        run.font.size  = Pt(9)
        run.font.name  = 'Calibri'
        run.font.color.rgb = WHITE

    # Data rows
    for ri, row_data in enumerate(rows):
        drow = t.rows[ri + 1]
        bg   = alt_fill if ri % 2 == 0 else "FFFFFF"
        for ci, (val, w) in enumerate(zip(row_data, col_widths)):
            cell = drow.cells[ci]
            cell.width = Inches(w)
            set_cell_borders(cell, "CCCCCC")
            set_cell_bg(cell, bg)
            p = cell.paragraphs[0]
            p.paragraph_format.space_before = Pt(3)
            p.paragraph_format.space_after  = Pt(3)
            is_oos = str(val).strip().upper() in ("OOS", "OUT OF SCOPE")
            is_tbd = str(val).strip().upper() in ("TBD", "SCOPE DEPENDENT", "N/A")
            run = p.add_run(str(val) if val is not None else "—")
            run.font.size = Pt(9)
            run.font.name = 'Calibri'
            if is_oos:
                run.font.color.rgb = OOS_RED
                run.bold = True
            elif is_tbd:
                run.font.color.rgb = RGBColor(0x88, 0x88, 0x88)
            else:
                run.font.color.rgb = BODY_TEXT
    doc.add_paragraph()

# ══════════════════════════════════════════════════════════════════════════════
# COVER PAGE
# ══════════════════════════════════════════════════════════════════════════════

# Top rule
rule("1A294A", size=24)

# Agency / Document meta
p = doc.add_paragraph()
p.paragraph_format.space_before = Pt(6)
run = p.add_run("DIGITAL & CREATIVE AGENCY")
run.font.size = Pt(9); run.font.name = 'Calibri'
run.font.color.rgb = RGBColor(0x88, 0x88, 0x99)
run.bold = True

p = doc.add_paragraph()
p.paragraph_format.space_before = Pt(2)
p.paragraph_format.space_after  = Pt(0)
run = p.add_run("Scope of Work 2026")
run.bold = True; run.font.size = Pt(28)
run.font.name = 'Calibri'; run.font.color.rgb = DARK_NAVY

p = doc.add_paragraph()
p.paragraph_format.space_before = Pt(4)
run = p.add_run("Retainer Agreement  ·  Annual Digital & Social Creative Services")
run.font.size = Pt(11); run.font.name = 'Calibri'
run.font.color.rgb = ACCENT

rule("007AC2", size=6)

# Meta row
meta = [
    ("Retainer Value", "PKR 400,000 / month"),
    ("Contract Period", "January – December 2026"),
    ("OOS Commission", "10% agency markup on all out-of-scope work"),
    ("Rush Rate", "1.5× standard rate card"),
    ("Document Status", "Proposed — Pending Client Sign-off"),
]
make_table(["Term", "Detail"], meta, [2.3, 4.0], header_bg="1A294A")

doc.add_paragraph()
add_note(
    "This Scope of Work applies to a single brand and its associated SKUs. "
    "New brand innovations, line extensions, or additional brands require a separate MRG and SOW addendum."
)

# Page break
doc.add_page_break()

# ══════════════════════════════════════════════════════════════════════════════
# 1. OBJECTIVE
# ══════════════════════════════════════════════════════════════════════════════
add_heading1("1. Objective & Service Overview")
add_body(
    "Always-on digital creative and content support to fuel upper- and mid-funnel marketing, "
    "strengthen brand salience, and improve performance across paid, owned, and earned channels.",
    bold=False
)
add_body(
    "The agency will provide audience and cultural insights, platform best practices, content calendars, "
    "communications and channel strategy inputs, creative ideation, production, and campaign reporting "
    "aligned to the brand's annual marketing agenda."
)

# ══════════════════════════════════════════════════════════════════════════════
# 2. IN-SCOPE DELIVERABLES
# ══════════════════════════════════════════════════════════════════════════════
add_heading1("2. In-Scope Deliverables (Monthly Retainer)")

# 2A Platform Content
add_heading2("2A  Platform Content Production")
scope_rows = [
    # Platform | Service | Deliverable / Volume | Notes
    ("Facebook & Instagram",
     "Static / GIF / Cinemagraph / Animated Video / Carousels / Canvas",
     "14 assets/month (create + convert demand)",
     "Includes all platform ad formats; shoot-based assets billed separately per rate card"),

    ("Facebook & Instagram",
     "Organic Instagram Stories",
     "12 Stories/month",
     "Can be deployed organically or with paid media investment"),

    ("Facebook & Instagram",
     "Event Coverage",
     "Out of Scope",
     "Basic mobile coverage available as OOS addition; extended video / pro camera charged separately. Internet provision beyond 4G is a separate cost."),

    ("Facebook & Instagram",
     "Live Streaming",
     "Out of Scope",
     "Requires dedicated internet connection + equipment. Internal coordination: PKR 25,000"),

    ("YouTube",
     "Video Post / Animated Video",
     "14 assets/month (create + convert demand)",
     "Shoot costs billed separately. Fully new animated videos or full revamps quoted per scope."),

    ("YouTube",
     "Pre-Roll Ads",
     "Up to 3 video edits/month (max 30 sec each), up to 3 iterations per video",
     "Shoot costs billed separately"),

    ("YouTube",
     "Video Adapts for Shorts",
     "14 adapts/month for YouTube Shorts",
     "Adapted from existing approved video assets"),

    ("YouTube",
     "Interactive Video",
     "Out of Scope",
     ""),

    ("TikTok",
     "Reels / All Ad Formats",
     "14 assets/month (made from existing content)",
     "Social-first, platform-native edits from approved footage"),

    ("Banner / Display Ads",
     "Search Ads (Google)",
     "Brief filled and managed by digital agency",
     ""),

    ("Banner / Display Ads",
     "Static / Animated GDN Banners",
     "1 set of GDN assets/month",
     "First set included in retainer. Additional sets per rate card (PKR 4,500/size). Animated banners require full redevelopment per iteration."),

    ("Banner / Display Ads",
     "Google Lightbox Ads",
     "Out of Scope",
     ""),

    ("Banner / Display Ads",
     "Sizmek Banner Ads",
     "Out of Scope",
     "PKR 20,000 per size (rate card)"),

    ("Banner / Display Ads",
     "Sizmek Rich Media Ads",
     "Out of Scope",
     ""),
]

make_table(
    ["Platform", "Service / Format", "Deliverable / Volume", "Notes"],
    scope_rows,
    [1.5, 1.9, 1.6, 1.3],
    header_bg="007AC2"
)

# 2B Platform Plans & Partnerships
add_heading2("2B  Platform-Specific Plans & Partnerships")
plans_rows = [
    ("Independent Instagram Plan", "Up to 2 standalone plans/year (separate from MRG plans)", ""),
    ("TikTok Plan", "Included in platform planning scope", "Quantum and cadence to be mutually aligned"),
    ("E-Commerce", "Included in scope where applicable", "Platform and channel to be defined per campaign"),
    ("Partnerships (All Platforms)", "Digital planning support for partnership activations", "Execution costs may vary"),
]
make_table(
    ["Service", "Scope", "Notes"],
    plans_rows,
    [2.0, 2.4, 1.9],
    header_bg="007AC2"
)

# 2C MRGs
add_heading2("2C  Market Review & Growth (MRG) Decks — Strategy")
add_body(
    "2 MRG strategy decks per brand per year. Additional MRGs available as OOS at agency commission. "
    "Each MRG includes:"
)
for item in [
    "Full exhaustive strategy and creative direction deck",
    "Messaging architecture and content pillars",
    "Big ideas and campaign territories (typically 1–2 concept routes; additional routes as OOS)",
    "Messaging frameworks by audience, funnel stage, and platform",
    "Static design treatments: 2 per brand per year",
]:
    add_bullet(item)

# ══════════════════════════════════════════════════════════════════════════════
# 3. STRATEGY & ALWAYS-ON SERVICES
# ══════════════════════════════════════════════════════════════════════════════
add_heading1("3. Strategy, Planning & Always-On Services")
add_body(
    "The following services are included in the monthly retainer and form the strategic backbone "
    "of the agency relationship:"
)
ao_rows = [
    ("Planning & Ideation", "Campaign and always-on content planning based on brand brief", "Ongoing"),
    ("Content Calendar", "Full monthly content calendar with platform-native recommendations", "Shared by the 15th for the following month"),
    ("Asset Scheduling", "Asset details shared with media agency (MS/Publicis)", "By the 20th each month"),
    ("Creative Design", "Platform-appropriate creative designs for all digital mediums", "Per campaign brief"),
    ("Platform Maintenance & Hygiene", "Profile upkeep, bio updates, pinned posts, cover art", "Ongoing"),
    ("Competitive Intelligence", "Fortnightly scanning; monthly summary with competitor content, ER benchmarks, paid signals, and actionable implications", "Monthly summary deck"),
    ("Digital & Creative Consultation", "Strategic and creative advisory as required", "On request"),
    ("Monthly Planning Alignment", "Agency–client planning sync for following month", "5th of each month"),
    ("Adapts for All Platforms", "Resizing and adaptation of approved creative for all relevant placements", "Included in retainer"),
]
make_table(
    ["Service", "Description", "Cadence / SLA"],
    ao_rows,
    [1.8, 3.3, 1.2],
    header_bg="007AC2"
)

add_note(
    "Social listening, community management, and response templates require a separate dedicated listening scope "
    "and are not included in this retainer."
)
add_note(
    "Analytics and paid media reporting are managed by the media agency. The creative agency will provide "
    "qualitative creative learnings and audience insights as part of monthly reviews."
)

# ══════════════════════════════════════════════════════════════════════════════
# 4. SLAs & WORKFLOW
# ══════════════════════════════════════════════════════════════════════════════
doc.add_page_break()
add_heading1("4. Service Level Agreements & Workflow")

add_heading2("4A  Brief Acceptance")
sla_brief = [
    ("Brief Receipt Acknowledgement", "Within 1 business day", "Flag all missing inputs or dependencies"),
    ("Clarification Questions + Proposed Timeline", "Within 2 business days", "Shared in writing for client sign-off"),
]
make_table(["Milestone", "SLA", "Notes"], sla_brief, [2.3, 1.5, 2.5])

add_heading2("4B  Creative Development Turnaround")
sla_dev = [
    ("Standard (BAU) campaigns — first concepts", "10 business days from brief sign-off", ""),
    ("Priority campaigns — first concepts", "5 business days from brief sign-off", "Rush fee applies if lead time < 3 business days"),
    ("First full creative route with mockups / storyboards", "7 business days from concept approval", "Timeline depends on volume of creatives; mutually aligned per project"),
    ("Minor amends (copy / colour / size changes)", "≤ 2 business days", ""),
    ("Major amends (layout / concept changes)", "≤ 4 business days", ""),
    ("Max rounds of revisions in scope", "3 rounds", "Additional rounds billed as OOS"),
]
make_table(["Milestone", "SLA", "Notes"], sla_dev, [2.4, 1.9, 2.0])

add_heading2("4C  Monthly Planning Calendar")
cal_rows = [
    ("5th", "Monthly planning alignment meeting — agency + client"),
    ("15th", "Content calendar shared by agency for following month"),
    ("20th", "Final asset details shared with media agency (MS/Publicis)"),
    ("28th", "Final production assets delivered to media agency"),
    ("10 days before go-live", "Calendar locked — post-lock changes require a change request + revised timeline"),
    ("5 days before go-live", "Calendar shared with media agency for trafficking"),
]
make_table(["Day of Month", "Milestone"], cal_rows, [1.8, 4.5])

add_heading2("4D  Internal Brand Sign-Off")
add_body(
    "Client / brand team to provide sign-off within 2 business days of receiving final assets. "
    "Delays in sign-off will cascade to delivery timelines with no agency liability."
)

add_heading2("4E  Rush & Same-Day Policy")
rush_rows = [
    ("< 48 hours lead time", "1.5× standard rate card"),
    ("< 24 hours lead time", "1.5× standard rate card (subject to feasibility)"),
    ("Same-day delivery", "Not accepted by agency unless an exception is made in critical cases"),
]
make_table(["Lead Time", "Charge"], rush_rows, [2.5, 3.8])

# ══════════════════════════════════════════════════════════════════════════════
# 5. MEASUREMENT & REPORTING
# ══════════════════════════════════════════════════════════════════════════════
add_heading1("5. Measurement, Reporting & Optimization")

add_heading2("5A  Campaign Performance (Post-Campaign Analysis)")
add_body(
    "Post-Campaign Analysis (PCA) is led by the media agency and delivered by the 7th day after campaign end. "
    "The creative agency contributes qualitative creative learnings and audience insights as part of the "
    "monthly joint review session."
)

add_heading2("5B  Quantitative KPIs (Media Agency Dashboard)")
quant_items = [
    "Reach and impressions",
    "Engagement rate — by post and by format",
    "Click-through rate (CTR)",
    "Video view-through rate (VTR)",
    "Saves and shares",
    "Follower growth",
    "Website sessions and conversions",
    "ROAS (where applicable)",
    "Benchmark vs. previous 3 months",
]
for item in quant_items:
    add_bullet(item)

add_heading2("5C  Agency-Owned KPIs")
kpi_rows = [
    ("Content Cadence", "≥ 14 posts/month per brand", "Aligned"),
    ("Turnaround Compliance", "≥ 95% of deliverables meet agreed SLA timelines", "Aligned"),
    ("Revision Efficiency", "≥ 80% of projects completed within 3 rounds of revisions", "Aligned"),
    ("Insight-Led Optimization", "Minimum 1 data-driven creative optimization applied per following campaign", "Aligned"),
    ("Video View-Through", "≥ 25% increase in complete views on short-form video (month-on-month)",
     "Dependent on media investment, platform algorithm, and audience targeting — shared accountability"),
]
make_table(
    ["KPI", "Target", "Status"],
    kpi_rows,
    [2.0, 3.2, 1.1]
)

# ══════════════════════════════════════════════════════════════════════════════
# 6. OUT-OF-SCOPE RATE CARD
# ══════════════════════════════════════════════════════════════════════════════
doc.add_page_break()
add_heading1("6. Out-of-Scope Rate Card (PKR)")
add_body(
    "All work outside the retainer scope will be quoted and approved in advance. "
    "A 10% agency commission applies to all third-party OOS costs. "
    "Scope-dependent items are quoted individually based on brief."
)

rate_rows = [
    ("3D Animation", "Up to 6-second video", "45,000", "360° product rotate on 2D. No shading, lighting, simulation, or post-production."),
    ("3D Animation — Detailed", "6–12 seconds", "Scope Dependent", ""),
    ("3D Pack Shots", "Per SKU", "25,000", ""),
    ("Static Post", "From scratch", "20,000", ""),
    ("Static Post", "Adapt / resize", "10,000", ""),
    ("Animated Post", "From scratch", "30,000", ""),
    ("Animated Post", "Adapt", "10,000", ""),
    ("Static Adapt", "Resize for additional placement", "10,000", ""),
    ("AR Filter", "From scratch", "Scope Dependent", ""),
    ("Case Study Video", "Up to 3 min (design + animation)", "250,000", ""),
    ("Chatbot", "Scope dependent", "60,000", ""),
    ("Concept Card Design", "Existing concept", "25,000", ""),
    ("Concept Card Design", "New concept + design", "40,000", ""),
    ("Content Writing", "Per article", "8,000", ""),
    ("DVC Concept", "30 seconds", "150,000", ""),
    ("Event Coverage", "Depends on scope", "N/A", "Quoted per event"),
    ("GDN Banners", "Per size", "4,500", "8 standard GDN sizes with simple animation: ~PKR 24,000/set"),
    ("Google Lightbox Ad", "Scope dependent", "N/A", ""),
    ("Interactive Video", "Scope dependent", "N/A", ""),
    ("Key Visual Design", "From scratch", "45,000", "May vary based on scope"),
    ("Logo Design", "—", "50,000", "May vary based on scope"),
    ("Mobile Application", "Scope dependent", "N/A", ""),
    ("OOH Adapts", "—", "15,000", ""),
    ("Packaging Adaptation", "—", "20,000", ""),
    ("Packaging Concept", "From scratch", "75,000", ""),
    ("Packaging Design", "Existing concept", "40,000", ""),
    ("Packaging Design", "New design", "60,000", ""),
    ("Packaging Edits", "—", "22,500", ""),
    ("PIP / Scroll / Logo", "For TV", "40,000", ""),
    ("PPT Design", "Per slide", "N/A", ""),
    ("ROTO", "Scope dependent", "N/A", ""),
    ("Script Writing", "—", "35,000", ""),
    ("Shoot Ideation / Moodboard", "—", "35,000", ""),
    ("Shoot (Photo or Video)", "Scope dependent", "N/A", "Quoted per brief"),
    ("Sizmek Banner", "1 size", "20,000", ""),
    ("Trade Artwork Adapts", "—", "15,000", ""),
    ("TVC Announcer — Concept", "—", "Scope Dependent", ""),
    ("TVC Announcer — Storyboard + Script", "—", "Scope Dependent", ""),
    ("Video — Subtitle (30 sec)", "—", "18,000", ""),
    ("Video — Copy Change", "—", "18,000", ""),
    ("Video Adapt", "—", "20,000", ""),
    ("Video Edit — Pack Shot Change (no ROTO)", "—", "40,000", ""),
    ("Voice Over (VO)", "Scope + talent dependent", "N/A", ""),
    ("Website Development", "Scope dependent", "N/A", ""),
    ("Whiteboard Animation", "Scope dependent", "N/A", ""),
    ("Product Photography", "Scope dependent", "N/A", ""),
    ("Game Development", "Scope dependent", "N/A", ""),
    ("Application Development", "Scope dependent", "N/A", ""),
]

make_table(
    ["Service", "Spec / Scope", "PKR", "Notes"],
    rate_rows,
    [2.2, 1.6, 1.0, 1.5],
    header_bg="1A294A"
)

# ══════════════════════════════════════════════════════════════════════════════
# 7. EXCLUSIONS & COMMERCIAL TERMS
# ══════════════════════════════════════════════════════════════════════════════
add_heading1("7. Exclusions, Assumptions & Commercial Terms")

add_heading2("7A  General Exclusions")
exclusions = [
    "Paid media buying, trafficking, or campaign management (managed by the media agency).",
    "Quantitative analytics dashboard and paid performance reporting (media agency responsibility).",
    "Dedicated social listening, community management, or 24/7 response service.",
    "Live streaming (requires dedicated internet connection, equipment, and third-party support).",
    "Any videography or photography shoot — quoted and approved separately per brief.",
    "New brand innovations or line extensions not covered under the existing brand SKU scope.",
    "Sizmek rich media, Google Lightbox, interactive video, and app development are out of scope.",
    "Internet provision beyond 4G devices at events.",
]
for e in exclusions:
    add_bullet(e)

add_heading2("7B  Commercial Terms")
comm_rows = [
    ("Monthly Retainer", "PKR 400,000", "Payable in advance on the 1st of each month"),
    ("OOS Commission", "10%", "Applied to all OOS project costs and third-party spends"),
    ("Rush Surcharge", "1.5× rate card", "Applies to briefs with < 48-hour lead time"),
    ("Additional Revision Rounds", "Billed per rate card", "Beyond 3 rounds included in scope"),
    ("Travel / Accommodation", "At cost + 10%", "For events / shoots requiring agency resource travel"),
    ("Currency", "Pakistani Rupee (PKR)", "All figures inclusive of applicable taxes unless stated"),
]
make_table(
    ["Item", "Rate / Policy", "Notes"],
    comm_rows,
    [2.0, 2.0, 2.3],
    header_bg="1A294A"
)

add_heading2("7C  Key Assumptions")
assumptions = [
    "All creative briefs will be shared in writing with clear objectives, audience, key message, and mandatories.",
    "Brand teams will provide timely feedback within agreed SLA windows. Delays reset delivery timelines.",
    "The agency is not responsible for performance outcomes driven by media spend decisions, audience targeting, or platform algorithm changes.",
    "MRG strategy decks are collaborative — agency presents, client provides direction within 5 business days.",
    "All third-party costs (talent, props, location, licensing) are passed through at cost + 10% commission.",
    "This SOW supersedes any previous retainer agreement and takes effect from 1 January 2026.",
]
for a in assumptions:
    add_bullet(a)

# Footer note
doc.add_paragraph()
rule("1A294A", 6)
p = doc.add_paragraph()
p.paragraph_format.space_before = Pt(4)
run = p.add_run(
    "Document prepared by Digital & Creative Agency  ·  June 2026  ·  Confidential & Proprietary  ·  "
    "Subject to execution of formal agreement"
)
run.font.size  = Pt(8)
run.font.name  = 'Calibri'
run.font.color.rgb = RGBColor(0x88, 0x88, 0x99)
run.italic = True
p.alignment = WD_ALIGN_PARAGRAPH.CENTER

# ── Save ───────────────────────────────────────────────────────────────────────
out = "/sessions/friendly-hopeful-ritchie/mnt/outputs/SOW_2026_Digital_Agency.docx"
doc.save(out)
print(f"Saved: {out}")
