# -*- coding: utf-8 -*-
from pathlib import Path
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import mm
from reportlab.pdfbase.cidfonts import UnicodeCIDFont
from reportlab.pdfbase import pdfmetrics
from reportlab.platypus import Paragraph, Table, TableStyle
from reportlab.lib.styles import ParagraphStyle
from reportlab.lib.utils import ImageReader
from reportlab.lib.enums import TA_LEFT, TA_CENTER
from math import sin, cos, pi

ROOT = Path('/Users/bot1/Volumes/root_for_ai/AI工作区/良渚_商业手册_品牌合作PDF_20260602_1526')
OUT = ROOT / 'deliverables/良渚博物院文创品牌及IP授权合作手册_A4_品牌方直发版_20260602.pdf'
OUT.parent.mkdir(parents=True, exist_ok=True)

pdfmetrics.registerFont(UnicodeCIDFont('STSong-Light'))
FONT = 'STSong-Light'
W, H = A4

# 良渚调性：鸡骨白、浅玉灰绿、璧青、琮黄、少量朱砂。
BONE = colors.HexColor('#FFFDF3')
BONE2 = colors.HexColor('#F7F4E7')
JADE_PALE = colors.HexColor('#E8F2EA')
JADE_SOFT = colors.HexColor('#C7DED2')
JADE = colors.HexColor('#5B8F7E')
JADE_DARK = colors.HexColor('#173D35')
JADE_DEEP = colors.HexColor('#0F2F2A')
GOLD = colors.HexColor('#C69A3C')
GOLD_LIGHT = colors.HexColor('#E8CB7B')
CINNABAR = colors.HexColor('#A74E3F')
INK = colors.HexColor('#183B34')
MUTED = colors.HexColor('#61756B')
WHITE80 = colors.Color(1,1,1,.82)

styles = {
    'kicker': ParagraphStyle('kicker', fontName=FONT, fontSize=8.5, leading=11, textColor=GOLD, wordWrap='CJK'),
    'kicker_d': ParagraphStyle('kicker_d', fontName=FONT, fontSize=8.5, leading=11, textColor=GOLD_LIGHT, wordWrap='CJK'),
    'cover': ParagraphStyle('cover', fontName=FONT, fontSize=36, leading=43, textColor=BONE, wordWrap='CJK'),
    'h1': ParagraphStyle('h1', fontName=FONT, fontSize=24, leading=30, textColor=INK, wordWrap='CJK'),
    'h1_d': ParagraphStyle('h1_d', fontName=FONT, fontSize=24, leading=30, textColor=BONE, wordWrap='CJK'),
    'h2': ParagraphStyle('h2', fontName=FONT, fontSize=15.5, leading=20, textColor=INK, wordWrap='CJK'),
    'h2_d': ParagraphStyle('h2_d', fontName=FONT, fontSize=15.5, leading=20, textColor=colors.HexColor('#FFF3CD'), wordWrap='CJK'),
    'lead': ParagraphStyle('lead', fontName=FONT, fontSize=12.6, leading=18, textColor=INK, wordWrap='CJK'),
    'lead_d': ParagraphStyle('lead_d', fontName=FONT, fontSize=12.6, leading=18, textColor=BONE, wordWrap='CJK'),
    'body': ParagraphStyle('body', fontName=FONT, fontSize=9.4, leading=14.1, textColor=colors.HexColor('#40584F'), wordWrap='CJK'),
    'body_d': ParagraphStyle('body_d', fontName=FONT, fontSize=9.4, leading=14.1, textColor=colors.HexColor('#E8EFE5'), wordWrap='CJK'),
    'small': ParagraphStyle('small', fontName=FONT, fontSize=7.7, leading=10.5, textColor=MUTED, wordWrap='CJK'),
    'small_d': ParagraphStyle('small_d', fontName=FONT, fontSize=7.7, leading=10.5, textColor=colors.HexColor('#D5DED4'), wordWrap='CJK'),
    'center': ParagraphStyle('center', fontName=FONT, fontSize=9.2, leading=13, alignment=TA_CENTER, textColor=colors.HexColor('#40584F'), wordWrap='CJK'),
}

def P(text, style='body'):
    return Paragraph(str(text).replace('\n','<br/>'), styles[style])

def draw_p(c, text, x, y_top, w, h, style='body'):
    p = P(text, style)
    pw, ph = p.wrap(w, h)
    p.drawOn(c, x, y_top - ph)
    return ph

def background(c, kind='light'):
    if kind == 'dark':
        c.setFillColor(JADE_DEEP); c.rect(0,0,W,H,stroke=0,fill=1)
        c.setFillColor(colors.Color(.12,.34,.29,1)); c.circle(W*.74,H*.80,70*mm,stroke=0,fill=1)
        c.setFillColor(colors.Color(.79,.61,.24,.34)); c.circle(W*1.02,H*.10,82*mm,stroke=0,fill=1)
        c.setFillColor(colors.Color(.77,.90,.82,.12)); c.circle(W*.10,H*.12,62*mm,stroke=0,fill=1)
    elif kind == 'split':
        c.setFillColor(BONE); c.rect(0,0,W,H,stroke=0,fill=1)
        c.setFillColor(JADE_PALE); c.rect(W*.58,0,W*.42,H,stroke=0,fill=1)
        c.setFillColor(colors.Color(.78,.88,.82,.45)); c.circle(W*.96,H*.82,66*mm,stroke=0,fill=1)
        c.setFillColor(colors.Color(.79,.61,.24,.14)); c.circle(W*.12,H*.08,60*mm,stroke=0,fill=1)
    else:
        c.setFillColor(BONE); c.rect(0,0,W,H,stroke=0,fill=1)
        c.setFillColor(JADE_PALE); c.circle(W*.08,H*.10,68*mm,stroke=0,fill=1)
        c.setFillColor(colors.Color(.79,.61,.24,.14)); c.circle(W*.94,H*.90,62*mm,stroke=0,fill=1)

# 轻纹样：不使用具体文物图，只做现代几何装饰。
def motif(c, x, y, r, dark=False):
    c.saveState()
    c.translate(x,y)
    c.setStrokeColor(colors.Color(1,1,1,.16) if dark else colors.Color(.09,.24,.20,.10))
    c.setLineWidth(.8)
    c.circle(0,0,r,stroke=1,fill=0)
    c.circle(0,0,r*.62,stroke=1,fill=0)
    for i in range(4):
        ang = i*pi/2 + pi/4
        c.line(cos(ang)*r*.20, sin(ang)*r*.20, cos(ang)*r*.86, sin(ang)*r*.86)
    c.restoreState()

def header(c, kicker, title, page_no, kind='light'):
    dark = kind == 'dark'
    background(c, kind)
    draw_p(c, kicker, 17*mm, H-22*mm, 170*mm, 9*mm, 'kicker_d' if dark else 'kicker')
    draw_p(c, title, 17*mm, H-37*mm, 170*mm, 35*mm, 'h1_d' if dark else 'h1')
    motif(c, W-29*mm, H-27*mm, 15*mm, dark)
    footer(c, page_no, dark)

def footer(c, page_no, dark=False):
    c.setStrokeColor(colors.Color(1,1,1,.22) if dark else colors.Color(.1,.24,.2,.16))
    c.setLineWidth(.35); c.line(17*mm, 15*mm, W-17*mm, 15*mm)
    c.setFont(FONT, 7.3); c.setFillColor(colors.Color(1,1,1,.48) if dark else colors.Color(.1,.24,.2,.42))
    c.drawRightString(W-17*mm, 9.5*mm, f'{page_no:02d}')

def card(c, x, y_top, w, h, title, body, tag=None, dark=False, fill=None):
    y = y_top-h
    c.setFillColor(fill if fill else (colors.Color(1,1,1,.78) if not dark else colors.Color(1,1,1,.09)))
    c.setStrokeColor(colors.Color(.10,.28,.24,.11) if not dark else colors.Color(1,1,1,.17))
    c.roundRect(x,y,w,h,6*mm,stroke=1,fill=1)
    pad=4.4*mm; cur=y_top-pad
    if tag:
        draw_p(c, tag, x+pad, cur, w-2*pad, 8*mm, 'kicker_d' if dark else 'kicker'); cur-=8*mm
    draw_p(c, title, x+pad, cur, w-2*pad, 19*mm, 'h2_d' if dark else 'h2'); cur-=20*mm
    draw_p(c, body, x+pad, cur, w-2*pad, max(10*mm,h-31*mm), 'body_d' if dark else 'body')

def stat(c, x, y_top, w, h, number, label, body=''):
    y=y_top-h
    c.setFillColor(colors.Color(1,1,1,.78)); c.setStrokeColor(colors.Color(.10,.28,.24,.10))
    c.roundRect(x,y,w,h,6*mm,stroke=1,fill=1)
    c.setFont(FONT, 21); c.setFillColor(JADE_DARK); c.drawCentredString(x+w/2, y_top-14*mm, number)
    c.setFont(FONT, 9.2); c.setFillColor(GOLD); c.drawCentredString(x+w/2, y_top-24*mm, label)
    if body:
        draw_p(c, body, x+4*mm, y_top-31*mm, w-8*mm, h-33*mm, 'center')

def draw_table(c, data, x, y_top, widths, fs=8.2):
    pdata = [[P(cell,'body') for cell in row] for row in data]
    t=Table(pdata, colWidths=widths, repeatRows=1)
    t.setStyle(TableStyle([
        ('FONTNAME',(0,0),(-1,-1),FONT),
        ('FONTSIZE',(0,0),(-1,-1),fs),
        ('VALIGN',(0,0),(-1,-1),'TOP'),
        ('BACKGROUND',(0,0),(-1,0),colors.Color(.79,.61,.24,.16)),
        ('TEXTCOLOR',(0,0),(-1,0),colors.HexColor('#76571A')),
        ('BACKGROUND',(0,1),(-1,-1),colors.Color(1,1,1,.76)),
        ('GRID',(0,0),(-1,-1),.25,colors.Color(.10,.28,.24,.13)),
        ('LEFTPADDING',(0,0),(-1,-1),5),('RIGHTPADDING',(0,0),(-1,-1),5),
        ('TOPPADDING',(0,0),(-1,-1),5),('BOTTOMPADDING',(0,0),(-1,-1),5),
    ]))
    tw,th=t.wrap(sum(widths),H)
    t.drawOn(c,x,y_top-th)
    return th

def timeline_item(c, x, y, n, title, body, dark=False):
    c.setFillColor(GOLD); c.circle(x+4*mm, y-4*mm, 4*mm, stroke=0, fill=1)
    c.setFillColor(colors.white); c.setFont(FONT, 7.2); c.drawCentredString(x+4*mm, y-6.4*mm, n)
    draw_p(c, title, x+13*mm, y, 62*mm, 12*mm, 'h2_d' if dark else 'h2')
    draw_p(c, body, x+13*mm, y-13*mm, 62*mm, 30*mm, 'body_d' if dark else 'body')

c = canvas.Canvas(str(OUT), pagesize=A4)

# 01 Cover
background(c,'dark')
draw_p(c, 'LIANGZHU MUSEUM · CULTURAL CREATIVE BRAND & IP LICENSING', 17*mm, H-24*mm, 170*mm, 10*mm, 'kicker_d')
draw_p(c, '良渚博物院\n文创品牌及IP授权\n合作手册', 17*mm, H-58*mm, 146*mm, 130*mm, 'cover')
c.setStrokeColor(GOLD_LIGHT); c.setLineWidth(1.15); c.line(17*mm, H-143*mm, 91*mm, H-143*mm)
draw_p(c, '世界遗产 · 文明圣地 · 国家平台', 17*mm, H-155*mm, 150*mm, 20*mm, 'lead_d')
draw_p(c, '活化文化遗产，赋能当代生活', 17*mm, H-176*mm, 150*mm, 20*mm, 'body_d')
for x,y,r in [(158*mm,93*mm,25*mm),(178*mm,68*mm,13*mm),(143*mm,57*mm,10*mm)]: motif(c,x,y,r,True)
c.setFont(FONT, 8.2); c.setFillColor(colors.Color(1,1,1,.58)); c.drawString(17*mm, 21*mm, '良渚博物院文创品牌及IP授权合作手册')
footer(c,1,True); c.showPage()

# 02 Liangzhu culture basics
header(c,'01 · 良渚文化基本情况','良渚文化：中华五千多年文明史的重要标识',2,'light')
card(c,17*mm,H-76*mm,176*mm,54*mm,'文明源头与世界遗产','良渚文化是新石器时代晚期中国长江下游环太湖流域的一支考古学文化，距今约5300年—4300年。作为良渚文化的权力与信仰中心，良渚古城遗址于2019年7月6日成功列入《世界遗产名录》，在世界范围内为中华五千多年文明史树立了重要标识，被誉为“实证中华五千年文明史的圣地”。')
stat(c,17*mm,H-148*mm,40*mm,43*mm,'5300+','距今年代','良渚文化距今约5300—4300年')
stat(c,63*mm,H-148*mm,40*mm,43*mm,'2019','列入世遗','良渚古城遗址列入《世界遗产名录》')
stat(c,109*mm,H-148*mm,40*mm,43*mm,'1+3','展示格局','良渚博物院联动三大遗址公园')
stat(c,155*mm,H-148*mm,38*mm,43*mm,'国家级','文旅地标','彰显中华五千年文明底蕴')
card(c,17*mm,H-211*mm,84*mm,50*mm,'“1+3”全域遗产价值展示格局','良渚博物院联动良渚古城、瑶山、老虎岭等遗址公园，统筹构建全域遗产价值展示格局，系统打造彰显中华五千年文明底蕴的国家级标杆文旅地标。','空间体系')
card(c,109*mm,H-211*mm,84*mm,50*mm,'品牌合作的文化底座','良渚的核心价值并非单一图案或符号，而是由文明实证、世界遗产、遗址空间、文物体系和当代文创转化共同组成的文化资产。','合作基础')
footer(c,2); c.showPage()

# 03 1+3 spaces
header(c,'02 · 展示空间体系','良渚博物院与三大遗址公园',3,'split')
card(c,17*mm,H-80*mm,84*mm,66*mm,'良渚博物院','集收藏、研究、展示和宣传良渚文化功能为一体的考古遗址博物馆，被评为“国家一级博物馆”、第二届全国文博百强文创产品单位，被授予“印记——中华文明文化传播标识”。基本陈列展览主题为“良渚是实证中华五千多年文明史的圣地”。','核心展示窗口')
card(c,109*mm,H-80*mm,84*mm,66*mm,'良渚古城遗址公园','良渚古城遗址厚重历史文化最典型、最直接的物质载体，是体验和感悟“中华五千多年文明”的重要场所。规划总面积14.33平方公里，城址区展示面积3.66平方公里，设置城门与城墙、河道与作坊、莫角山宫殿、反山王陵等遗址展示区。','遗址现场')
card(c,17*mm,H-160*mm,84*mm,52*mm,'瑶山遗址公园','依托自然山丘而建，是一处祭坛和高等级墓地组成的复合遗址，营建于良渚文化早期。','祭坛与高等级墓地')
card(c,109*mm,H-160*mm,84*mm,52*mm,'老虎岭遗址公园','目前良渚古城遗址唯一一处向公众展示水利系统剖面结构的遗址点。良渚古城外围水利系统是中国迄今发现最早的大型水利工程遗址，也是目前已发现的世界上最早的堤坝系统之一。','水利系统展示')
card(c,17*mm,H-231*mm,176*mm,38*mm,'从遗产展示到当代生活','良渚文化以博物馆、遗址公园、水利系统、祭坛与王陵等多元空间，形成可参观、可体验、可传播、可转化的文化内容体系。','全域价值')
footer(c,3); c.showPage()

# 04 Cultural creative industry
header(c,'03 · 良渚文化创意产业','深耕文物资源活态化传承',4,'light')
card(c,17*mm,H-76*mm,176*mm,48*mm,'文创产业定位','良渚博物院深耕文物资源活态化传承，体系化推进品牌IP培育及载体，推动良渚文明实现可观、可触、可品、可感的深度传播，持续为中华五千年文明血脉注入时代动能。')
stat(c,17*mm,H-145*mm,40*mm,45*mm,'11','覆盖品类','布局并覆盖日用家居、贵金属等11大品类')
stat(c,63*mm,H-145*mm,40*mm,45*mm,'800+','在线产品','在线销售产品约800余款')
stat(c,109*mm,H-145*mm,40*mm,45*mm,'4亿+','销售规模','2025年总销售额已突破4亿元')
stat(c,155*mm,H-145*mm,38*mm,45*mm,'多项','行业荣誉','红点设计奖、“中国礼物”金奖等大奖')
card(c,17*mm,H-214*mm,84*mm,56*mm,'产品特征','持续迭代推出兼具亲民属性、精工品质、独特辨识度与市场竞争力的标杆文创产品。','产品矩阵')
card(c,109*mm,H-214*mm,84*mm,56*mm,'品牌生态','现已构建“良渚+”品牌生态矩阵，以文创产品、品牌IP、跨界合作和渠道销售共同推动良渚文明的当代表达。','良渚+')
footer(c,4); c.showPage()

# 05 IP development position and architecture
header(c,'04 · 良渚文化IP资源开发','世界遗产、文明圣地、国家平台',5,'dark')
card(c,17*mm,H-83*mm,176*mm,62*mm,'品牌定位','良渚文化品牌以“世界遗产、文明圣地、国家平台”三重价值为战略基点，秉持“活化文化遗产，赋能当代生活”的使命担当，聚焦“五千年中国看良渚”的叙事主线，塑造兼具深厚历史底蕴与鲜明东方文明标识度的超级文化品牌。','BRAND POSITION',True)
# hierarchy diagram
c.setStrokeColor(colors.Color(1,1,1,.26)); c.setLineWidth(.6)
levels=[('一级品牌','良渚文化','总品牌，传递鲜明的世界遗产标识'),('二级品牌','良渚博物院 / 良渚古城','代表文化展示、文旅体验的重要展示窗口'),('三级品牌','多元化子品牌','面向各个生活场景，实现文化与市场无缝衔接')]
y=H-118*mm
for i,(lvl,name,desc) in enumerate(levels):
    card(c,25*mm,y,160*mm,34*mm,name,desc,lvl,True)
    if i<2:
        c.setStrokeColor(GOLD_LIGHT); c.line(W/2,y-34*mm,W/2,y-40*mm)
    y-=44*mm
card(c,17*mm,H-253*mm,176*mm,27*mm,'知识产权保护基础','为保障品牌IP的规范发展和知识产权保护，良渚文化在顶层设计上搭建了层次清晰、覆盖广泛的三级分众化品牌体系，累计完成600余件作品的标准化确权。','600余件作品标准化确权',True)
footer(c,5,True); c.showPage()

# 06 Material resource library
header(c,'05 · 品牌素材资源库','色彩资源库与纹样基因库',6,'light')
card(c,17*mm,H-84*mm,84*mm,72*mm,'良渚色彩资源库','完整呈现良渚文化色彩系统研究成果，包含1100余组色彩数据、396种良渚特有颜色、8个良渚核心色、39个良渚原创色名，降低跨领域品牌开发文创的学术门槛，提升开发效率。','COLOR SYSTEM')
card(c,109*mm,H-84*mm,84*mm,72*mm,'良渚纹样基因库','经科学系统性梳理、标准化提取与数字化建档的良渚纹样专有矢量数据库。近百组良渚纹样数据均包含器型图、器型展开图、线稿、色板、单体纹样、高清图片、纹样属性信息等全套信息。','PATTERN SYSTEM')
# visual blocks
for i,(x,col,name) in enumerate([(23,JADE_DARK,'璧青'),(58,JADE,'玉绿'),(93,JADE_SOFT,'浅玉'),(128,GOLD,'琮黄'),(163,CINNABAR,'玉沁')]):
    c.setFillColor(col); c.roundRect(x*mm,H-148*mm,25*mm,25*mm,4*mm,stroke=0,fill=1)
    c.setFont(FONT,8); c.setFillColor(INK if i in [2,3] else colors.white); c.drawCentredString((x+12.5)*mm,H-162*mm,name)
card(c,17*mm,H-221*mm,176*mm,45*mm,'可支持的开发环节','品牌素材资源库为产品开发、包装设计、礼盒设计、视觉传播、空间陈列与文创衍生提供系统化素材支撑，让良渚文化从学术研究成果转化为可落地、可识别、可应用的品牌资产。','标准化资产')
footer(c,6); c.showPage()

# 07 Authorization forms & cases
header(c,'06 · 品牌授权形式','特定品类授权、联合开发、跨界联名',7,'split')
card(c,17*mm,H-81*mm,54*mm,76*mm,'特定品类授权','开放特定品类版权授权，合作方依托良渚IP设计、生产与市场化运作，借力品牌影响力赋能产品市场竞争力与商业价值提升。\n\n代表性案例：良渚博物院授予周大福贵金属品类独家IP授权，联合打造满足文化收藏价值和实用价值双重属性的良渚文化系列饰品。','01')
card(c,78*mm,H-81*mm,54*mm,76*mm,'联合开发','以双方资源整合、优势互补为基础，共同投入要素开展项目共创，实行风险共担、成果共享机制，通过协同创新实现品牌价值跃升。\n\n代表性案例：良渚玉器精灵系列盲盒、良渚·萌兽探琮-毛绒盲盒等产品荣获“文博会礼物·新锐奖”。','02')
card(c,139*mm,H-81*mm,54*mm,76*mm,'跨界联名','以多品牌跨界协同开展市场运营为主，通过联名产品共创、品牌活动联动，实现客群互通、优势互补与品牌势能叠加。\n\n代表性案例：良渚文化×特步联名系列产品，将良渚标志性纹样和色彩融入跑鞋青云2.0及跑服设计。','03')
card(c,17*mm,H-184*mm,176*mm,52*mm,'文化资本向经济资本转化','良渚博物院IP资源授权工作通过特定品类授权、联合开发、跨界联名等方式，开发了系列“文化资本”向“经济资本”转化的经典案例，不仅印证良渚文化IP强大的市场吸引力，更推动文化价值与商业价值的有效协同与良性互促。','IP RESOURCE DEVELOPMENT')
footer(c,7); c.showPage()

# 08 Rights list and policy
header(c,'07 · 良渚文化IP合作征集','分层权益支持 + 年度奖励激励',8,'light')
card(c,17*mm,H-82*mm,176*mm,52*mm,'良渚文化品牌合作权益清单','围绕“分层权益支持+年度奖励激励”的原则，构建并正式发布《良渚文化品牌合作权益清单》，精准提供差异化支持，以覆盖不同合作层级企业的需求。')
card(c,17*mm,H-151*mm,84*mm,55*mm,'2026年良渚文创共创权益政策','推出2026年良渚文创共创权益政策，给予合作方最高礼遇、实施最好政策、提供最优服务，为各行各业可持续发展全面保驾护航。','权益政策')
card(c,109*mm,H-151*mm,84*mm,55*mm,'全链条赋能','从官方活动的VIP受邀到自有空间的免费使用，从官方渠道的精准宣传到核心美学基因库的全面开放，让更多力量参与良渚文化的活态传承。','支持内容')
draw_table(c,[['权益方向','内容'],['活动礼遇','官方活动VIP受邀'],['空间支持','自有空间免费使用'],['传播支持','官方渠道精准宣传'],['素材支持','核心美学基因库开放']],17*mm,H-226*mm,[45*mm,131*mm],fs=8.5)
footer(c,8); c.showPage()

# 09 Co-creation invitation
header(c,'08 · 良渚文创共创合作征集','共商品牌授权、合作开发、招商入驻等多元合作',9,'dark')
draw_p(c,'良渚文化，是历史的厚重书卷，更是时代的鲜活IP。',17*mm,H-76*mm,168*mm,26*mm,'h2_d')
card(c,17*mm,H-124*mm,176*mm,56*mm,'面向社会广泛征集','良渚文创招募共创合作伙伴，面向社会广泛征集文创合作意向及设计开发方案，向拥有文创梦想的优质企业、高校设计团队及个人发出诚挚邀请，共商品牌授权、合作开发、招商入驻等多元合作，共创兼具文化价值、时代特色、当代审美的文创产品，共绘良渚文创发展新图景。','CO-CREATION',True)
card(c,17*mm,H-195*mm,176*mm,50*mm,'合作方式','欢迎以产品授权、合作开发、联名推广等多种方式加入共创计划，实现资源共享、产品共创、市场共拓、品牌共铸。','JOIN THE PLAN',True)
# QR placeholder / contact panel
c.setFillColor(colors.Color(1,1,1,.10)); c.setStrokeColor(colors.Color(1,1,1,.22)); c.roundRect(17*mm,37*mm,176*mm,43*mm,6*mm,stroke=1,fill=1)
draw_p(c,'文创设计、IP联名合作意向可扫描良渚文创二维码联系',25*mm,66*mm,105*mm,18*mm,'lead_d')
c.setFillColor(colors.Color(1,1,1,.16)); c.roundRect(150*mm,44*mm,25*mm,25*mm,3*mm,stroke=0,fill=1)
# QR-like placeholder grid purely decorative, no false QR content
for i in range(5):
    for j in range(5):
        if (i*j+i+j)%3==0:
            c.setFillColor(colors.Color(1,1,1,.46)); c.rect((153+i*4)*mm,(47+j*4)*mm,2.4*mm,2.4*mm,stroke=0,fill=1)
footer(c,9,True); c.showPage()

c.save()
print(OUT)
print(OUT.exists(), OUT.stat().st_size)
