# -*- coding: utf-8 -*-
"""Build 3-page A4 company profile for 巴德 (generic, no addressee).

Outputs:
  - HTML (3 x A4 sheets, brand header/footer on every sheet)
  - DOCX (uses the 之江 company-profile DOCX as style/header/footer template)
"""
import os
import sys
import html
from datetime import datetime

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

BASE = os.path.expanduser('~/Desktop/Hermes输出-工作类')
OUT_DIR = os.path.join(BASE, '对外物料', '公司介绍_巴德_20261103')
TEMPLATE = os.path.join(BASE, '对外物料', '公司资质文件_之江_20261102', '宝锐生物_公司介绍_之江_20261102_V01.docx')
sys.path.insert(0, os.path.join(BASE, '脚本'))
import brand_kit as BK

os.makedirs(OUT_DIR, exist_ok=True)

DATE_CN = '2026 年 11 月'
COMPANY_CN = '珠海宝锐生物科技有限公司'
COMPANY_EN = 'Zhuhai Biori Biotechnology Co., Ltd.'
SLOGAN = '守护生命健康，缔造美好生活'
ADDR = '珠海市香洲区水岸一路 88 号'
TEL = '0756-8699969'
MAIL = 'marketing@biori.com'
SITE = 'www.biori.com'

# ---------------------------------------------------------------------------
# Shared content (facts only; sources: 之江版 company profile, 2026 general PPT,
# mRNA product catalogue, official qualification material)
# ---------------------------------------------------------------------------
KPI = [
    ('2012', '成立年份'),
    ('2.6 万㎡', '总部园区'),
    ('130+', '上市公司客户'),
    ('2,000+', '工业与科研客户'),
]

BIZ_ROWS = [
    ('诊断原料', '分子诊断用酶、预混液及辅助原料', 'qPCR / RT-qPCR、LAMP / RT-LAMP、分子酶、可冻干原料'),
    ('生命科学', '分子生物学、核酸提取纯化、NGS 建库、蛋白研究', 'PCR / qPCR 试剂、核酸提取试剂、文库构建、蛋白研究试剂'),
    ('生物医药', 'mRNA / circRNA 原料、HCD / HCP 检测、质量安全分析', 'IVT 酶、加帽与质控试剂、宿主细胞残留检测'),
]

TECH = [
    ('蛋白进化', '微孔板筛选（MTPS）、微流控高通量筛选（MHTS）与计算机辅助设计（CARD），用于提高酶的热稳定性、活性与底物适应性。'),
    ('重组表达与纯化', '工程菌株构建、三级种子库管理、高密度发酵、蛋白精细纯化，重视批间一致性。'),
    ('抗体与适配体', '抗体开发、适配体筛选及化学 / 配基修饰，用于高特异性、高灵敏度检测体系。'),
    ('工艺开发与应用', '从酶蛋白修饰、成品试剂配制到客户体系适配、冻干工艺开发与技术支持。'),
]

DIAG_CARDS = [
    ('分子诊断酶', 'Taq / Fast Taq / 高保真 DNA 聚合酶、逆转录酶、RNase 抑制剂、Bst / Tth、UNG；覆盖 PCR、qPCR、RT-qPCR、LAMP / RT-LAMP。'),
    ('预混液与可冻干原料', 'qPCR / RT-qPCR 探针法与染料法预混液、LAMP / RT-LAMP 预混液、可冻干原料；支持液态、冻干、直扩与全血样品。'),
    ('抗体与适配体', '抗体开发、适配体筛选与化学 / 配基修饰；面向免疫检测与高特异性识别体系。'),
    ('工艺与质量', '9 套 GMP 洁净车间、C / D 级洁净区、药用级纯化水与注射用水；按 ISO 9001 / ISO 13485 实施全周期质量管理。'),
]

DIAG_PRODUCTS = [
    ('扩增酶', 'Taq DNA Polymerase、Fast Taq V2、高保真 DNA 聚合酶', '常规 PCR、快速 PCR、高保真扩增'),
    ('逆转录', 'Reverse Transcriptase、RNase Inhibitor', 'RNA 检测、cDNA 合成、RT-qPCR'),
    ('预混液', 'qPCR / RT-qPCR 探针法、染料法预混液', '病原检测、基因表达、多重检测'),
    ('恒温扩增', 'LAMP / RT-LAMP 预混液与原料', 'POCT、现场检测、基层筛查'),
    ('可冻干原料', '可冻干预混液与辅助原料', '冻干型 IVD、POCT 试剂'),
    ('抗体 / 适配体', '抗体开发、适配体筛选与修饰', '免疫检测、特异性识别'),
]

DIAG_FORMS = [
    ('2–8℃', '液态保存'),
    ('冻干', '冻干型试剂'),
    ('直扩 / 全血', '免提取与全血样品'),
    ('单管', '全预混、单管反应'),
]

TIMELINE = [
    ('2012', '公司成立'),
    ('2017', '国家高新技术企业首次认定'),
    ('2018', 'ISO 9001 质量管理体系'),
    ('2021', '广东省专精特新中小企业'),
    ('2023', '省工程技术研究中心 / 市企业技术中心'),
    ('2024', 'ISO 13485 / 省博士后创新实践基地'),
]

APPS = [
    ('病原核酸检测', 'qPCR / RT-qPCR、多重扩增与 LAMP / RT-LAMP 体系。'),
    ('POCT 与现场检测', '冻干型试剂、直扩与全血样品，适配便携与现场场景。'),
    ('基因表达与科研', '逆转录、cDNA 合成、qPCR / RT-qPCR 预混液。'),
]

PHARMA_BLOCKS = [
    ('mRNA / circRNA 原料全链条',
     '质粒模板线性化酶（BspQ I、Bsa I、EcoR I）、T7 RNA 聚合酶（常用、耐热、3.0 低 dsRNA）、牛痘病毒加帽酶、2′-O-甲基转移酶、RNase 抑制剂、无机焦磷酸酶、DNase I、RNase R、核苷酸与帽类似物，以及转录、加帽、circRNA 合成和 RNA 质控试剂盒。'),
    ('HCD / HCP 质量检测',
     '提供宿主细胞 DNA（HCD）与宿主细胞蛋白（HCP）残留检测产品及定制化服务，用于生物制品生产过程中的质量安全分析。'),
    ('生产与质量',
     'mRNA 原料按 GMP 级生产、执行 ISO 13485；公司配备 9 套 GMP 洁净车间、C / D 级洁净区与药用级纯化水 / 注射用水系统，按 ISO 9001 / ISO 13485 实施全周期质量管理。'),
]

PHARMA_DATA = [
    ('T7 RNA 聚合酶 3.0', 'dsRNA 残留', '<1 μg/mg（对照 >10 μg/mg）；等量转录产量约 183–185 μg'),
    ('T7 高效转录试剂盒', '模板转化效率', '1 μg 模板可获得 ≥200 μg RNA 产物'),
    ('牛痘病毒加帽酶', '加帽率', '单次反应最高可实现 100% 加帽'),
    ('circRNA 一步法合成试剂盒', '产物纯度', '毛细管电泳检测纯度 >95%'),
]

QUAL = [
    ('ISO 9001:2015', '质量管理体系认证'),
    ('ISO 13485:2016', '医疗器械质量管理体系认证'),
    ('国家高新技术企业', '国家高新技术企业认定'),
    ('国家专精特新“小巨人”企业', '工业和信息化部认定'),
    ('广东省专精特新中小企业', '广东省认定'),
    ('广东省分子诊断原料酶工程技术研究中心', '广东省科技厅认定'),
    ('珠海市企业技术中心', '珠海市认定'),
    ('广东省博士后创新实践基地', '广东省人力资源和社会保障厅批准设立'),
]

# ---------------------------------------------------------------------------
# HTML
# ---------------------------------------------------------------------------
CSS = r"""
@page { size: A4; margin: 0; }
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  background: #e8eef7;
  color: #1f2937;
  font-family: "Times New Roman", "Songti SC", "STSong", "SimSun", "宋体", serif;
  -webkit-print-color-adjust: exact !important;
  print-color-adjust: exact !important;
}
.sheet {
  width: 210mm; height: 297mm; position: relative; overflow: hidden;
  background: #fff; margin: 0 auto 8mm; padding: 24mm 18mm 21mm;
  page-break-after: always; break-after: page;
}
.sheet:last-child { page-break-after: auto; break-after: auto; }
.bior-header, .bior-footer { position: absolute; left: 18mm; right: 18mm; }
.bior-header { top: 7mm; padding: 0 !important; background: transparent !important; border: 0 !important; box-shadow: none !important; }
.bior-footer { bottom: 7mm; padding: 0 !important; background: transparent !important; border: 0 !important; box-shadow: none !important; }
.bior-footer .bior-footer-slogan { font-size: 8.1pt !important; letter-spacing: .08em; }
.bior-footer .bior-footer-meta { font-size: 6.6pt !important; color: #64748b !important; }
.bior-footer .bior-footer-extra { display: none !important; }
.page-no { position: absolute; right: 18mm; bottom: 3.2mm; font-size: 7.2pt; color: #94a3b8; }
.doc-kicker { font-size: 7.5pt; letter-spacing: .22em; color: #0f766e; font-weight: 700; margin: 0 0 3mm; }
h1 { font-size: 20pt; line-height: 1.18; color: #0f3d6e; margin: 0 0 2.5mm; font-weight: 700; letter-spacing: .02em; }
.company-cn { font-size: 12.6pt; color: #0f3d6e; font-weight: 700; margin-top: 1mm; }
.company-en { font-family: "Times New Roman", serif; font-size: 8.6pt; color: #64748b; margin-top: 1mm; letter-spacing: .02em; }
.title-rule { height: 1.1mm; width: 28mm; background: #0ea5a4; margin: 4mm 0 5mm; }
h2 { font-size: 11.6pt; color: #0f3d6e; margin: 0 0 2.2mm; padding: 0 0 1.4mm; border-bottom: .35mm solid #dbe4ef; font-weight: 700; }
h2 .num { color: #0ea5a4; font-family: "Times New Roman", serif; margin-right: 2mm; font-size: 9.2pt; }
h3 { font-size: 9.6pt; color: #0f3d6e; margin: 3mm 0 1.5mm; font-weight: 700; }
p { font-size: 9.25pt; line-height: 1.62; margin: 0 0 2.2mm; text-align: justify; }
.lead { font-size: 10pt; line-height: 1.7; color: #243447; }
.muted { color: #64748b; }
.small { font-size: 7.6pt; line-height: 1.5; color: #64748b; }
.kpi-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 2.2mm; margin: 1mm 0 5mm; }
.kpi { border: .3mm solid #dbe4ef; border-top: 1.1mm solid #0ea5a4; background: #f8fbfe; padding: 2.6mm 2.6mm 2.2mm; }
.kpi b { display: block; font-family: "Times New Roman", serif; font-size: 16.5pt; line-height: 1; color: #0f3d6e; font-weight: 700; }
.kpi span { display: block; font-size: 7.5pt; color: #64748b; margin-top: 1.6mm; }
table { width: 100%; border-collapse: collapse; table-layout: fixed; }
th, td { border: .25mm solid #dbe4ef; padding: 1.9mm 2.1mm; vertical-align: middle; text-align: left; }
th { background: #0f3d6e; color: #fff; font-size: 8pt; font-weight: 700; letter-spacing: .02em; }
td { font-size: 8.15pt; line-height: 1.45; }
td b { color: #0f3d6e; }
.biz td:first-child { font-weight: 700; color: #0f3d6e; background: #f6f9fd; width: 18%; }
.biz td:nth-child(2) { width: 38%; }
.biz td:nth-child(3) { width: 44%; }
.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 2.2mm 5mm; }
.tech { border-left: .9mm solid #0ea5a4; padding: 0 0 0 3mm; }
.tech b { display: block; font-size: 9pt; color: #0f3d6e; margin-bottom: 1mm; }
.tech p { font-size: 8.4pt; line-height: 1.55; margin: 0; }
.cards2 { display: grid; grid-template-columns: 1fr 1fr; gap: 2.4mm; }
.card { border: .3mm solid #dbe4ef; background: #fbfdff; padding: 2.8mm 3mm; }
.card b { display: block; font-size: 9.2pt; color: #0f3d6e; margin-bottom: 1.4mm; }
.card p { font-size: 8.25pt; line-height: 1.55; margin: 0; }
.forms { display: grid; grid-template-columns: repeat(4, 1fr); gap: 2mm; margin: 2mm 0 3mm; }
.form { background: #0f3d6e; color: #fff; padding: 2.4mm 2.6mm; }
.form b { display: block; font-family: "Times New Roman", serif; font-size: 11.5pt; line-height: 1.05; }
.form span { display: block; font-size: 7.2pt; color: #d8ecff; margin-top: 1.2mm; }
.callout { border-left: 1.1mm solid #0ea5a4; background: #f4fbfa; padding: 2.6mm 3mm; margin: 2.5mm 0 0; }
.callout p { font-size: 8.2pt; line-height: 1.55; margin: 0; }
.three { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2.4mm; }
.three .card b { font-size: 9pt; }
.three .card p { font-size: 7.95pt; line-height: 1.5; }
.data-table td:first-child { font-weight: 700; color: #0f3d6e; width: 25%; }
.data-table td:nth-child(2) { width: 17%; color: #0f766e; font-weight: 700; }
.innovation { border: .3mm solid #dbe4ef; background: #f8fbfe; padding: 2.5mm 3mm; margin: 2.5mm 0 0; }
.innovation p { font-size: 8pt; line-height: 1.55; margin: 0; }
.timeline { display: grid; grid-template-columns: repeat(6, 1fr); gap: 2mm; margin: 1mm 0 0; }
.tl { border-top: .8mm solid #0ea5a4; padding-top: 1.8mm; }
.tl b { display: block; font-family: "Times New Roman", serif; font-size: 10.5pt; color: #0f3d6e; line-height: 1; }
.tl span { display: block; font-size: 7.2pt; line-height: 1.35; color: #475569; margin-top: 1.4mm; }
.apps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2.2mm; }
.app { border: .3mm solid #dbe4ef; background: #fbfdff; padding: 2.4mm 2.8mm; }
.app b { display: block; font-size: 8.8pt; color: #0f3d6e; margin-bottom: 1mm; }
.app p { font-size: 8pt; line-height: 1.45; margin: 0; }
.qual td:nth-child(odd) { font-weight: 700; color: #0f3d6e; width: 27%; background: #f6f9fd; }
.qual td:nth-child(even) { width: 23%; }
.coop { border-top: .4mm solid #dbe4ef; margin-top: 3mm; padding-top: 2.5mm; }
.coop p { font-size: 8.4pt; line-height: 1.6; margin: 0 0 1.2mm; }
.coop b { color: #0f3d6e; }
.footnote { font-size: 7.1pt; line-height: 1.45; color: #7b8794; margin-top: 2mm; }
@media print {
  body { background: #fff; }
  .sheet { margin: 0; box-shadow: none; }
}
"""


def H(tag, text, cls=''):
    return '<%s%s>%s</%s>' % (tag, (' class="%s"' % cls) if cls else '', text, tag)


def page1():
    kpis = ''.join('<div class="kpi"><b>%s</b><span>%s</span></div>' % (a, b) for a, b in KPI)
    biz = ''.join('<tr><td>%s</td><td>%s</td><td>%s</td></tr>' % row for row in BIZ_ROWS)
    tech = ''.join('<div class="tech"><b>%s</b><p>%s</p></div>' % (a, b) for a, b in TECH)
    timeline = ''.join('<div class="tl"><b>%s</b><span>%s</span></div>' % (a, b) for a, b in TIMELINE)
    return f'''<div class="sheet">
{BK.header_html(theme='light', tag='公司介绍')}
<div class="doc-kicker">BIORI BIOTECH · COMPANY PROFILE</div>
<h1>公司介绍</h1>
<div class="company-cn">{COMPANY_CN}</div>
<div class="company-en">{COMPANY_EN}</div>
<div class="title-rule"></div>
<div class="kpi-grid">{kpis}</div>
<p class="lead">宝锐生物成立于 2012 年，总部位于广东珠海，面向工业与科研用户提供生物原料与试剂解决方案。公司以蛋白进化、重组表达、抗体开发、适配体筛选、工艺开发及应用研究为技术平台，形成诊断原料、生命科学、生物医药三条业务线。</p>
<p>公司是国家高新技术企业、国家专精特新“小巨人”企业，建有广东省分子诊断原料酶工程技术研究中心、珠海市企业技术中心、广东省博士后创新实践基地；总部园区 2.6 万㎡，配备 9 套 GMP 洁净车间，通过 ISO 9001:2015 与 ISO 13485:2016 质量管理体系认证。</p>
<p>截至 2026 年 10 月，公司服务 130+ 上市公司客户、2,000+ 工业与科研客户，上线产品品类 3,000+。</p>
<h2><span class="num">01</span>业务板块</h2>
<table class="biz"><thead><tr><th>板块</th><th>主要内容</th><th>典型产品 / 服务方向</th></tr></thead><tbody>{biz}</tbody></table>
<h2><span class="num">02</span>技术平台</h2>
<div class="grid2">{tech}</div>
<h3>发展节点</h3>
<div class="timeline">{timeline}</div>
<div class="footnote">数据截至 2026 年 10 月；客户与产品数据按公司公开资料整理。具体资质、产品规格与验证数据以最新文件为准。</div>
{BK.footer_html('')}
<div class="page-no">1 / 3</div>
</div>'''


def page2():
    cards = ''.join('<div class="card"><b>%s</b><p>%s</p></div>' % (a, b) for a, b in DIAG_CARDS)
    prod = ''.join('<tr><td>%s</td><td>%s</td><td>%s</td></tr>' % row for row in DIAG_PRODUCTS)
    forms = ''.join('<div class="form"><b>%s</b><span>%s</span></div>' % (a, b) for a, b in DIAG_FORMS)
    apps = ''.join('<div class="app"><b>%s</b><p>%s</p></div>' % (a, b) for a, b in APPS)
    return f'''<div class="sheet">
{BK.header_html(theme='light', tag='诊断原料')}
<div class="doc-kicker">DIAGNOSTIC RAW MATERIALS</div>
<h1>诊断原料</h1>
<div class="company-en" style="font-size:9.4pt;color:#0f3d6e;margin-bottom:4mm">从分子酶、预混液到可冻干原料与体系适配</div>
<div class="title-rule"></div>
<p class="lead">诊断原料业务围绕分子诊断酶、预混液、可冻干原料和客户体系适配展开，服务 IVD、POCT 与病原检测客户。产品覆盖 PCR、qPCR、RT-qPCR、LAMP / RT-LAMP 等反应体系，并配套抗体与适配体平台。</p>
<div class="cards2">{cards}</div>
<h3>代表产品方向</h3>
<table><thead><tr><th style="width:17%">方向</th><th style="width:41%">代表产品</th><th style="width:42%">应用</th></tr></thead><tbody>{prod}</tbody></table>
<h3>产品形态</h3>
<div class="forms">{forms}</div>
<div class="callout"><p><b>诊断特色：</b>酶、预混液、可冻干原料与体系适配在同一条技术链上完成。公司资料列示，2–8℃ 液态保存、冻干型超灵敏、冻干型高灵敏直扩、全血直扩分型、单管稳定高灵敏等分子诊断试剂为国内首款；具体注册 / 备案信息以产品资料为准。</p></div>
<h3>典型应用</h3>
<div class="apps">{apps}</div>
<p style="margin-top:3mm">从原料筛选、体系优化到冻干工艺，宝锐按客户平台做适配；具体产品规格、验证数据与样品按项目对接。</p>
{BK.footer_html('')}
<div class="page-no">2 / 3</div>
</div>'''


def page3():
    blocks = ''.join('<div class="card"><b>%s</b><p>%s</p></div>' % (a, b) for a, b in PHARMA_BLOCKS)
    data = ''.join('<tr><td>%s</td><td>%s</td><td>%s</td></tr>' % row for row in PHARMA_DATA)
    qual = ''.join('<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>' % (QUAL[i][0], QUAL[i][1], QUAL[i+1][0], QUAL[i+1][1]) for i in range(0, len(QUAL), 2))
    return f'''<div class="sheet">
{BK.header_html(theme='light', tag='生物医药')}
<div class="doc-kicker">BIOPHARMA RAW MATERIALS &amp; QUALITY</div>
<h1>生物医药</h1>
<div class="company-en" style="font-size:9.4pt;color:#0f3d6e;margin-bottom:4mm">mRNA / circRNA 原料与 HCD / HCP 质量检测</div>
<div class="title-rule"></div>
<p class="lead">生物医药业务面向 mRNA / circRNA 药物与生物制品质量分析，提供 IVT 酶、加帽与质控试剂、HCD / HCP 检测产品及定制化服务。原料端覆盖从质粒模板线性化、体外转录、加帽到 RNA 质控的完整链条。</p>
<div class="three">{blocks}</div>
<h3>代表性数据</h3>
<table class="data-table"><thead><tr><th style="width:25%">产品</th><th style="width:17%">指标</th><th style="width:58%">结果</th></tr></thead><tbody>{data}</tbody></table>
<div class="innovation"><p><b>创新成果（公司资料列示）：</b>T7 RNA 聚合酶、RNase R、BspQ I、EcoR I 为国内首发；RNA Ladder、RNA 完整性检测试剂盒、circRNA 合成试剂盒为国内首创；mRNA 原料按 GMP 级生产、执行 ISO 13485，并完成 FDA DMF 备案。</p></div>
<h3>资质与荣誉</h3>
<table class="qual"><tbody>{qual}</tbody></table>
<div class="coop">
<p><b>合作接口：</b>诊断原料方向可对接分子酶、qPCR / RT-qPCR / LAMP 预混液、可冻干原料、抗体与适配体；生物医药方向可对接 mRNA / circRNA 原料、HCD / HCP 检测。合作方式包括原料供应、定制开发、体系适配与技术支持。</p>
<p class="small">{COMPANY_CN}　｜　{ADDR}　｜　电话 {TEL}　｜　{MAIL}　｜　{SITE}</p>
</div>
<div class="footnote">产品数据来自公司 mRNA 产品资料；具体规格、验证方法与批次数据以最新产品资料为准。</div>
{BK.footer_html('')}
<div class="page-no">3 / 3</div>
</div>'''


def build_html():
    brand_css = BK.CSS.replace('/* 白底顶栏变体（工作台页面） */', '/* 白底顶栏变体 */')
    html_doc = f'''<!DOCTYPE html>
<html lang="zh-CN"><head><meta charset="utf-8">
<title>宝锐生物 公司介绍</title>
<style>{brand_css}</style>
<style>{CSS}</style>
</head><body>
{page1()}
{page2()}
{page3()}
</body></html>'''
    out = os.path.join(OUT_DIR, '宝锐生物_公司介绍_巴德版_20261103_V01.html')
    with open(out, 'w', encoding='utf-8') as f:
        f.write(html_doc)
    return out


# ---------------------------------------------------------------------------
# DOCX
# ---------------------------------------------------------------------------
def _set_run_font(run, size=10.5, bold=False, color=None, east='宋体', latin='Times New Roman'):
    run.font.name = latin
    run.font.size = Pt(size)
    run.font.bold = bold
    rPr = run._element.get_or_add_rPr()
    rFonts = rPr.find(qn('w:rFonts'))
    if rFonts is None:
        rFonts = OxmlElement('w:rFonts'); rPr.append(rFonts)
    rFonts.set(qn('w:ascii'), latin)
    rFonts.set(qn('w:hAnsi'), latin)
    rFonts.set(qn('w:eastAsia'), east)
    if color:
        run.font.color.rgb = RGBColor.from_string(color)


def _para(doc, text='', size=10.5, bold=False, color=None, align=None, before=0, after=2, line=1.45, indent=None):
    p = doc.add_paragraph()
    pf = p.paragraph_format
    pf.space_before = Pt(before)
    pf.space_after = Pt(after)
    pf.line_spacing = line
    if align is not None:
        p.alignment = align
    if indent is not None:
        pf.first_line_indent = Cm(indent)
    r = p.add_run(text)
    _set_run_font(r, size=size, bold=bold, color=color)
    return p


def _heading(doc, text, num='', size=12.2):
    p = doc.add_paragraph()
    p.paragraph_format.space_before = Pt(7)
    p.paragraph_format.space_after = Pt(3)
    p.paragraph_format.keep_with_next = True
    if num:
        r0 = p.add_run(num + '  ')
        _set_run_font(r0, size=9.2, bold=True, color='0EA5A4')
    r = p.add_run(text)
    _set_run_font(r, size=size, bold=True, color='0F3D6E')
    # bottom border
    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'), '4')
    bottom.set(qn('w:space'), '2'); bottom.set(qn('w:color'), 'DBE4EF')
    pBdr.append(bottom); pPr.append(pBdr)
    return p


def _shade(cell, hex_color):
    tcPr = cell._tc.get_or_add_tcPr()
    shd = OxmlElement('w:shd')
    shd.set(qn('w:fill'), hex_color)
    tcPr.append(shd)


def _cell_text(cell, text, size=8.5, bold=False, color=None, align=WD_ALIGN_PARAGRAPH.LEFT):
    cell.text = ''
    p = cell.paragraphs[0]
    p.alignment = align
    p.paragraph_format.space_before = Pt(0)
    p.paragraph_format.space_after = Pt(0)
    p.paragraph_format.line_spacing = 1.25
    r = p.add_run(str(text))
    _set_run_font(r, size=size, bold=bold, color=color)
    tcPr = cell._tc.get_or_add_tcPr()
    tcMar = OxmlElement('w:tcMar')
    for side, val in [('top', 40), ('bottom', 40), ('left', 70), ('right', 70)]:
        el = OxmlElement('w:' + side)
        el.set(qn('w:w'), str(val)); el.set(qn('w:type'), 'dxa')
        tcMar.append(el)
    tcPr.append(tcMar)


def _table(doc, headers, rows, widths, header_fill='0F3D6E', font_size=8.5, bold_first_col=False):
    table = doc.add_table(rows=1, cols=len(headers))
    table.alignment = WD_TABLE_ALIGNMENT.CENTER
    table.autofit = False
    table.style = 'Table Grid'
    hdr = table.rows[0].cells
    for i, h in enumerate(headers):
        _cell_text(hdr[i], h, size=8.2, bold=True, color='FFFFFF')
        _shade(hdr[i], header_fill)
    for row in rows:
        cells = table.add_row().cells
        for i, val in enumerate(row):
            _cell_text(cells[i], val, size=font_size, bold=(bold_first_col and i == 0), color=('0F3D6E' if (bold_first_col and i == 0) else None))
    for row in table.rows:
        trPr = row._tr.get_or_add_trPr()
        cant = OxmlElement('w:cantSplit'); trPr.append(cant)
    for i, w in enumerate(widths):
        for row in table.rows:
            row.cells[i].width = Cm(w)
    return table


def build_docx():
    doc = Document(TEMPLATE)
    # clear body, keep sectPr (header/footer/page setup)
    body = doc.element.body
    for child in list(body):
        if child.tag.endswith('}sectPr'):
            continue
        body.remove(child)

    style = doc.styles['Normal']
    style.font.name = 'Times New Roman'
    style.font.size = Pt(10.5)
    style.element.rPr.rFonts.set(qn('w:eastAsia'), '宋体')
    style.paragraph_format.space_after = Pt(2)
    style.paragraph_format.line_spacing = 1.45

    # ---------------- Page 1 ----------------
    _para(doc, '公司介绍', size=20, bold=True, color='0F3D6E', after=1, line=1.1)
    _para(doc, COMPANY_CN, size=12.8, bold=True, color='0F3D6E', after=1, line=1.15)
    _para(doc, COMPANY_EN, size=8.8, color='64748B', after=5, line=1.0)
    # thin accent rule via paragraph bottom border
    p = doc.add_paragraph(); p.paragraph_format.space_after = Pt(5)
    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'), '12'); bottom.set(qn('w:space'), '1'); bottom.set(qn('w:color'), '0EA5A4')
    pBdr.append(bottom); pPr.append(pBdr)

    # KPI table
    kt = doc.add_table(rows=2, cols=4)
    kt.alignment = WD_TABLE_ALIGNMENT.CENTER
    kt.style = 'Table Grid'
    for i, (val, label) in enumerate(KPI):
        _cell_text(kt.rows[0].cells[i], val, size=16, bold=True, color='0F3D6E', align=WD_ALIGN_PARAGRAPH.CENTER)
        _shade(kt.rows[0].cells[i], 'F4F9FD')
        _cell_text(kt.rows[1].cells[i], label, size=7.8, color='64748B', align=WD_ALIGN_PARAGRAPH.CENTER)
        _shade(kt.rows[1].cells[i], 'F4F9FD')
    for row in kt.rows:
        trPr = row._tr.get_or_add_trPr(); trPr.append(OxmlElement('w:cantSplit'))
    _para(doc, '', size=2, after=1)

    _heading(doc, '公司概况', '01')
    _para(doc, '宝锐生物成立于 2012 年，总部位于广东珠海，面向工业与科研用户提供生物原料与试剂解决方案。公司以蛋白进化、重组表达、抗体开发、适配体筛选、工艺开发及应用研究为技术平台，形成诊断原料、生命科学、生物医药三条业务线。', size=9.8, line=1.55, after=2)
    _para(doc, '公司是国家高新技术企业、国家专精特新“小巨人”企业，建有广东省分子诊断原料酶工程技术研究中心、珠海市企业技术中心、广东省博士后创新实践基地；总部园区 2.6 万㎡，配备 9 套 GMP 洁净车间，通过 ISO 9001:2015 与 ISO 13485:2016 质量管理体系认证。', size=9.8, line=1.55, after=2)
    _para(doc, '截至 2026 年 10 月，公司服务 130+ 上市公司客户、2,000+ 工业与科研客户，上线产品品类 3,000+。', size=9.8, line=1.55, after=4)

    _heading(doc, '业务板块', '02')
    _table(doc, ['板块', '主要内容', '典型产品 / 服务方向'], BIZ_ROWS, [3.4, 6.3, 7.0], font_size=8.5, bold_first_col=True)
    _para(doc, '', size=2, after=1)
    _heading(doc, '技术平台', '03')
    for title, desc in TECH:
        p = doc.add_paragraph()
        p.paragraph_format.space_before = Pt(1); p.paragraph_format.space_after = Pt(1)
        p.paragraph_format.line_spacing = 1.45
        p.paragraph_format.left_indent = Cm(0.3)
        r = p.add_run('• ' + title + '：')
        _set_run_font(r, size=9.4, bold=True, color='0F3D6E')
        r2 = p.add_run(desc)
        _set_run_font(r2, size=9.1, color='1F2937')
    _para(doc, '发展节点', size=9.6, bold=True, color='0F3D6E', before=4, after=2)
    _table(doc, ['年份', '节点', '年份', '节点', '年份', '节点'],
           [(TIMELINE[0][0], TIMELINE[0][1], TIMELINE[1][0], TIMELINE[1][1], TIMELINE[2][0], TIMELINE[2][1]),
            (TIMELINE[3][0], TIMELINE[3][1], TIMELINE[4][0], TIMELINE[4][1], TIMELINE[5][0], TIMELINE[5][1])],
           [1.6, 3.8, 1.6, 3.8, 1.6, 3.8], font_size=7.4, bold_first_col=True)
    _para(doc, '数据截至 2026 年 10 月；客户与产品数据按公司公开资料整理。具体资质、产品规格与验证数据以最新文件为准。', size=7.2, color='7B8794', before=3, after=0, line=1.3)

    doc.add_page_break()

    # ---------------- Page 2 ----------------
    _para(doc, '诊断原料', size=20, bold=True, color='0F3D6E', after=1, line=1.1)
    _para(doc, '从分子酶、预混液到可冻干原料与体系适配', size=10.2, bold=True, color='0F3D6E', after=4, line=1.2)
    p = doc.add_paragraph(); p.paragraph_format.space_after = Pt(4)
    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'), '12'); bottom.set(qn('w:space'), '1'); bottom.set(qn('w:color'), '0EA5A4')
    pBdr.append(bottom); pPr.append(pBdr)
    _para(doc, '诊断原料业务围绕分子诊断酶、预混液、可冻干原料和客户体系适配展开，服务 IVD、POCT 与病原检测客户。产品覆盖 PCR、qPCR、RT-qPCR、LAMP / RT-LAMP 等反应体系，并配套抗体与适配体平台。', size=9.8, line=1.55, after=4)
    # 2x2 cards as table
    _table(doc, ['能力', '内容'], [(a, b) for a, b in DIAG_CARDS], [3.6, 13.1], font_size=8.6, bold_first_col=True)
    _para(doc, '', size=2, after=1)
    _heading(doc, '代表产品方向', '01', size=11.8)
    _table(doc, ['方向', '代表产品', '应用'], DIAG_PRODUCTS, [3.0, 7.2, 6.5], font_size=8.3, bold_first_col=True)
    _para(doc, '', size=2, after=1)
    _heading(doc, '产品形态', '02', size=11.8)
    _table(doc, ['形态', '说明'], DIAG_FORMS, [3.8, 12.9], font_size=8.8, bold_first_col=True)
    _para(doc, '', size=2, after=1)
    _para(doc, '诊断特色：酶、预混液、可冻干原料与体系适配在同一条技术链上完成。公司资料列示，2–8℃ 液态保存、冻干型超灵敏、冻干型高灵敏直扩、全血直扩分型、单管稳定高灵敏等分子诊断试剂为国内首款；具体注册 / 备案信息以产品资料为准。', size=8.8, line=1.55, after=3)
    _para(doc, '典型应用', size=9.6, bold=True, color='0F3D6E', before=2, after=2)
    _table(doc, ['应用', '内容'], APPS, [4.2, 12.5], font_size=8.2, bold_first_col=True)
    _para(doc, '从原料筛选、体系优化到冻干工艺，宝锐按客户平台做适配；具体产品规格、验证数据与样品按项目对接。', size=9.2, line=1.55, before=3, after=0)

    doc.add_page_break()

    # ---------------- Page 3 ----------------
    _para(doc, '生物医药', size=20, bold=True, color='0F3D6E', after=1, line=1.1)
    _para(doc, 'mRNA / circRNA 原料与 HCD / HCP 质量检测', size=10.2, bold=True, color='0F3D6E', after=4, line=1.2)
    p = doc.add_paragraph(); p.paragraph_format.space_after = Pt(4)
    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'), '12'); bottom.set(qn('w:space'), '1'); bottom.set(qn('w:color'), '0EA5A4')
    pBdr.append(bottom); pPr.append(pBdr)
    _para(doc, '生物医药业务面向 mRNA / circRNA 药物与生物制品质量分析，提供 IVT 酶、加帽与质控试剂、HCD / HCP 检测产品及定制化服务。原料端覆盖从质粒模板线性化、体外转录、加帽到 RNA 质控的完整链条。', size=9.6, line=1.5, after=3)
    for title, desc in PHARMA_BLOCKS:
        p = doc.add_paragraph()
        p.paragraph_format.space_before = Pt(2); p.paragraph_format.space_after = Pt(1)
        p.paragraph_format.line_spacing = 1.45
        r = p.add_run('• ' + title + '：')
        _set_run_font(r, size=9.2, bold=True, color='0F3D6E')
        r2 = p.add_run(desc)
        _set_run_font(r2, size=8.8, color='1F2937')
    _heading(doc, '代表性数据', '01', size=11.8)
    _table(doc, ['产品', '指标', '结果'], PHARMA_DATA, [4.2, 3.0, 9.5], font_size=8.0, bold_first_col=True)
    _para(doc, '创新成果（公司资料列示）：T7 RNA 聚合酶、RNase R、BspQ I、EcoR I 为国内首发；RNA Ladder、RNA 完整性检测试剂盒、circRNA 合成试剂盒为国内首创；mRNA 原料按 GMP 级生产、执行 ISO 13485，并完成 FDA DMF 备案。', size=8.2, line=1.5, before=3, after=3)
    _heading(doc, '资质与荣誉', '02', size=11.8)
    qual_rows = [(QUAL[i][0], QUAL[i][1], QUAL[i+1][0], QUAL[i+1][1]) for i in range(0, len(QUAL), 2)]
    _table(doc, ['资质 / 荣誉', '说明', '资质 / 荣誉', '说明'], qual_rows, [4.2, 4.1, 4.2, 4.2], font_size=7.6, bold_first_col=True)
    _para(doc, '合作接口：诊断原料方向可对接分子酶、qPCR / RT-qPCR / LAMP 预混液、可冻干原料、抗体与适配体；生物医药方向可对接 mRNA / circRNA 原料、HCD / HCP 检测。合作方式包括原料供应、定制开发、体系适配与技术支持。', size=8.8, line=1.55, before=3, after=2)
    _para(doc, COMPANY_CN + '　｜　' + ADDR + '　｜　电话 ' + TEL + '　｜　' + MAIL + '　｜　' + SITE, size=8.0, color='475569', after=1)
    _para(doc, '产品数据来自公司 mRNA 产品资料；具体规格、验证方法与批次数据以最新产品资料为准。', size=7.2, color='7B8794', after=0, line=1.3)

    out = os.path.join(OUT_DIR, '宝锐生物_公司介绍_巴德版_20261103_V01.docx')
    # Let Word update PAGE / NUMPAGES fields when the file opens.
    settings = doc.settings.element
    if settings.find(qn('w:updateFields')) is None:
        update = OxmlElement('w:updateFields')
        update.set(qn('w:val'), 'true')
        settings.append(update)
    doc.save(out)
    return out


if __name__ == '__main__':
    h = build_html()
    d = build_docx()
    print('HTML', h, os.path.getsize(h))
    print('DOCX', d, os.path.getsize(d))
