New test

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

doc = Document()

# Page margins
section = doc.sections[0]
section.page_width  = Inches(8.5)
section.page_height = Inches(11)
section.top_margin    = Inches(0.7)
section.bottom_margin = Inches(0.7)
section.left_margin   = Inches(0.85)
section.right_margin  = Inches(0.85)

def set_cell_bg(cell, hex_color):
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 add_paragraph(doc, text, size=11, bold=False, color=None, align=WD_ALIGN_PARAGRAPH.LEFT, space_before=0, space_after=6, italic=False):
p = doc.add_paragraph()
p.alignment = align
p.paragraph_format.space_before = Pt(space_before)
p.paragraph_format.space_after  = Pt(space_after)
run = p.add_run(text)
run.bold   = bold
run.italic = italic
run.font.size = Pt(size)
run.font.name = ‘Arial’
if color:
run.font.color.rgb = RGBColor(*color)
return p

def add_colored_bar(doc, text, bg_hex, fg=(255,255,255), size=18):
“””Add a full-width shaded paragraph as a colour bar”””
t = doc.add_table(rows=1, cols=1)
t.style = ‘Table Grid’
cell = t.cell(0, 0)
set_cell_bg(cell, bg_hex)
# Remove borders
tc = cell._tc
tcPr = tc.get_or_add_tcPr()
for border_name in [‘top’,’left’,’bottom’,’right’,’insideH’,’insideV’]:
border = OxmlElement(f’w:{border_name}’)
border.set(qn(‘w:val’), ‘none’)
border.set(qn(‘w:sz’), ‘0’)
border.set(qn(‘w:space’), ‘0’)
border.set(qn(‘w:color’), ‘auto’)
tblBorders = OxmlElement(‘w:tblBorders’)
tblBorders.append(border)
# Write text
cell.paragraphs[0].clear()
p = cell.paragraphs[0]
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
p.paragraph_format.space_before = Pt(10)
p.paragraph_format.space_after  = Pt(10)
run = p.add_run(text)
run.bold = True
run.font.size = Pt(size)
run.font.name = ‘Arial’
run.font.color.rgb = RGBColor(*fg)
return t

def add_section_heading(doc, text):
p = doc.add_paragraph()
p.alignment = WD_ALIGN_PARAGRAPH.LEFT
p.paragraph_format.space_before = Pt(14)
p.paragraph_format.space_after  = Pt(4)
run = p.add_run(text.upper())
run.bold = True
run.font.size = Pt(10)
run.font.name = ‘Arial’
run.font.color.rgb = RGBColor(0, 102, 153)   # ocean blue
# underline rule: add bottom border to paragraph
pPr = p._p.get_or_add_pPr()
pBdr = OxmlElement(‘w:pBdr’)
bottom = OxmlElement(‘w:bottom’)
bottom.set(qn(‘w:val’), ‘single’)
bottom.set(qn(‘w:sz’), ‘6’)
bottom.set(qn(‘w:space’), ‘1’)
bottom.set(qn(‘w:color’), ‘006699’)
pBdr.append(bottom)
pPr.append(pBdr)
return p

OCEAN      = ‘006699’
OCEAN_DARK = ‘004F77’
SAND       = ‘F5F0E8’
WHITE      = ‘FFFFFF’

# ── HEADER BAR ──────────────────────────────────────────────────────────────
t = doc.add_table(rows=1, cols=1)
cell = t.cell(0,0)
set_cell_bg(cell, OCEAN_DARK)
tc = cell._tc
tcPr = tc.get_or_add_tcPr()
cell.paragraphs[0].clear()
p = cell.paragraphs[0]
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
p.paragraph_format.space_before = Pt(14)
p.paragraph_format.space_after  = Pt(2)
r1 = p.add_run(‘🌊  CoastalStay Management’)
r1.bold = True; r1.font.size = Pt(24); r1.font.name = ‘Arial’
r1.font.color.rgb = RGBColor(255,255,255)

p2 = cell.add_paragraph()
p2.alignment = WD_ALIGN_PARAGRAPH.CENTER
p2.paragraph_format.space_before = Pt(0)
p2.paragraph_format.space_after  = Pt(14)
r2 = p2.add_run(‘Your coastal apartment — earning more, worrying less.’)
r2.italic = True; r2.font.size = Pt(12); r2.font.name = ‘Arial’
r2.font.color.rgb = RGBColor(200, 230, 245)

# ── TAGLINE ──────────────────────────────────────────────────────────────────
add_paragraph(doc, ”, size=6, space_before=0, space_after=0)

# ── INTRO ────────────────────────────────────────────────────────────────────
add_section_heading(doc, ‘Who We Are’)
add_paragraph(doc,
‘CoastalStay Management is a specialist holiday-let management company focused ‘
‘entirely on beach and coastal properties. We handle everything — from stunning ‘
‘photography and multi-platform listings to guest check-ins, housekeeping, and ‘
‘maintenance — so you simply collect your income.’,
size=11, space_after=4)

# ── STATS ROW ────────────────────────────────────────────────────────────────
add_paragraph(doc, ”, size=4, space_before=8, space_after=0)
stats_table = doc.add_table(rows=1, cols=3)
stats_data = [
(‘95%’, ‘Average\nOccupancy Rate’),
(‘4.9★’, ‘Guest Rating\nAcross All Platforms’),
(‘38%’, ‘Higher Revenue vs.\nSelf-Managed Owners’),
]
for i, (stat, label) in enumerate(stats_data):
cell = stats_table.cell(0, i)
set_cell_bg(cell, OCEAN)
tc = cell._tc
tcPr = tc.get_or_add_tcPr()
cell.paragraphs[0].clear()
p = cell.paragraphs[0]
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
p.paragraph_format.space_before = Pt(10)
p.paragraph_format.space_after  = Pt(2)
r = p.add_run(stat)
r.bold = True; r.font.size = Pt(22); r.font.name = ‘Arial’
r.font.color.rgb = RGBColor(255,255,255)
p2 = cell.add_paragraph()
p2.alignment = WD_ALIGN_PARAGRAPH.CENTER
p2.paragraph_format.space_before = Pt(0)
p2.paragraph_format.space_after  = Pt(10)
r2 = p2.add_run(label)
r2.font.size = Pt(9); r2.font.name = ‘Arial’
r2.font.color.rgb = RGBColor(200, 230, 245)

# ── WHAT WE DO ───────────────────────────────────────────────────────────────
add_paragraph(doc, ”, size=6, space_before=8, space_after=0)
add_section_heading(doc, ‘What We Do For You’)

services_table = doc.add_table(rows=2, cols=2)
services = [
(‘📸  Professional Listing & Photography’,
‘We create eye-catching listings on Airbnb, Booking.com, Vrbo and our own direct-booking site — with professional photos that stop the scroll.’),
(‘📅  Dynamic Pricing & Revenue Management’,
‘Our pricing engine monitors demand, local events, and competitor rates in real time to maximise your income every single night.’),
(‘🤝  Guest Management & 24/7 Support’,
‘From enquiry to check-out, we handle all guest communication, key handover, and any issues that arise — you won\’t get a 2 am call.’),
(‘🧹  Housekeeping & Maintenance’,
‘Vetted local cleaning teams prepare the apartment to hotel standard after every stay. Routine maintenance is logged and managed on your behalf.’),
]
for idx, (title, desc) in enumerate(services):
row = idx // 2
col = idx % 2
cell = services_table.cell(row, col)
set_cell_bg(cell, SAND)
cell.paragraphs[0].clear()
p = cell.paragraphs[0]
p.paragraph_format.space_before = Pt(8)
p.paragraph_format.space_after  = Pt(2)
p.paragraph_format.left_indent  = Pt(6)
p.paragraph_format.right_indent = Pt(6)
r = p.add_run(title)
r.bold = True; r.font.size = Pt(10); r.font.name = ‘Arial’
r.font.color.rgb = RGBColor(0, 79, 119)
p2 = cell.add_paragraph(desc)
p2.paragraph_format.space_before = Pt(2)
p2.paragraph_format.space_after  = Pt(8)
p2.paragraph_format.left_indent  = Pt(6)
p2.paragraph_format.right_indent = Pt(6)
p2.runs[0].font.size = Pt(10); p2.runs[0].font.name = ‘Arial’

# ── WHY COASTALSTAY ──────────────────────────────────────────────────────────
add_paragraph(doc, ”, size=6, space_before=8, space_after=0)
add_section_heading(doc, ‘Why Apartment Owners Choose Us’)
bullet_points = [
‘No upfront fees — we earn only when you earn (commission-based model).’,
‘Transparent monthly owner statements with real-time dashboard access.’,
‘Local coastal market expertise: we know the high seasons, the hidden gems, and the guests who love them.’,
‘Fully insured operations and damage deposit management on every booking.’,
‘Dedicated owner account manager — a real person, not a helpdesk ticket.’,
]
for bp in bullet_points:
p = doc.add_paragraph(style=’List Bullet’)
p.paragraph_format.space_before = Pt(1)
p.paragraph_format.space_after  = Pt(3)
run = p.add_run(bp)
run.font.size = Pt(10.5); run.font.name = ‘Arial’

# ── TESTIMONIAL ──────────────────────────────────────────────────────────────
add_paragraph(doc, ”, size=5, space_before=10, space_after=0)
qt = doc.add_table(rows=1, cols=1)
qcell = qt.cell(0,0)
set_cell_bg(qcell, ‘004F77’)
qcell.paragraphs[0].clear()
qp = qcell.paragraphs[0]
qp.alignment = WD_ALIGN_PARAGRAPH.CENTER
qp.paragraph_format.space_before = Pt(10)
qp.paragraph_format.space_after = Pt(2)
qr = qp.add_run(‘”Since switching to CoastalStay our bookings went up 40% in the first season.’)
qr.italic = True; qr.font.size = Pt(11); qr.font.name = ‘Arial’
qr.font.color.rgb = RGBColor(255,255,255)
qp2 = qcell.add_paragraph()
qp2.alignment = WD_ALIGN_PARAGRAPH.CENTER
qp2.paragraph_format.space_before = Pt(0)
qp2.paragraph_format.space_after = Pt(10)
qr2 = qp2.add_run(‘I haven\’t had to think about the apartment once.”  — Maria T., apartment owner, Algarve’)
qr2.italic = True; qr2.font.size = Pt(10); qr2.font.name = ‘Arial’
qr2.font.color.rgb = RGBColor(180,220,240)

# ── CTA ──────────────────────────────────────────────────────────────────────
add_paragraph(doc, ”, size=6, space_before=10, space_after=0)
add_section_heading(doc, ‘Get a Free Revenue Estimate’)
add_paragraph(doc,
‘Wondering what your apartment could earn? We\’ll analyse your property and send you a ‘
‘personalised revenue projection — no strings attached.’,
size=11, space_after=4)

cta_table = doc.add_table(rows=1, cols=3)
cta_data = [
(‘📧‘, ‘[email protected]‘),
(‘📞‘, ‘+44 800 123 4567’),
(‘🌐‘, ‘www.coastalstay.com‘),
]
for i, (icon, detail) in enumerate(cta_data):
cell = cta_table.cell(0, i)
set_cell_bg(cell, ‘E8F4FA’)
tc = cell._tc; tcPr = tc.get_or_add_tcPr()
cell.paragraphs[0].clear()
p = cell.paragraphs[0]
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
p.paragraph_format.space_before = Pt(8)
p.paragraph_format.space_after  = Pt(2)
r = p.add_run(icon)
r.font.size = Pt(16); r.font.name = ‘Arial’
p2 = cell.add_paragraph(detail)
p2.alignment = WD_ALIGN_PARAGRAPH.CENTER
p2.paragraph_format.space_before = Pt(0)
p2.paragraph_format.space_after  = Pt(8)
p2.runs[0].bold = True; p2.runs[0].font.size = Pt(10); p2.runs[0].font.name = ‘Arial’
p2.runs[0].font.color.rgb = RGBColor(0, 79, 119)

# ── FOOTER ───────────────────────────────────────────────────────────────────
add_paragraph(doc, ”, size=5, space_before=6, space_after=0)
add_paragraph(doc,
‘CoastalStay Management Ltd  ·  Registered in England & Wales  ·  © 2026’,
size=8, align=WD_ALIGN_PARAGRAPH.CENTER, color=(150,150,150), space_after=0)

out = ‘/sessions/loving-great-archimedes/mnt/outputs/CoastalStay_Pitch_OnePager.docx’
doc.save(out)
print(‘Saved:’, out)