# -*- coding: utf-8 -*-
"""生成瑞士风可编辑 HTML 翻页 PPT（25 页，文字 contenteditable）"""
import os

OUT = '/Users/liuxinyuan/Desktop/Hermes输出-工作类/对外物料/客户宣讲_20260921/宝锐诊断原料_客户宣讲_瑞士风_26页_可编辑.html'

# 每页: (类型, HTML片段)。类型 cover/section/content/ending 决定配色
P = []
P.append(('cover', '''
  <div class="cover-body">
    <div class="cover-rule"></div>
    <div class="cover-main">
      <div class="kicker">DIAGNOSTIC RAW MATERIALS</div>
      <h1 contenteditable>诊断原料<br>整体解决方案</h1>
      <div class="cover-hr"></div>
      <p class="sub" contenteditable>分子诊断原料 · 从体系到货号的一站式对接</p>
    </div>
  </div>
  <div class="footline">珠海宝锐生物科技有限公司</div>'''))
P.append(('content', '''
  <div class="kicker">OVERVIEW</div>
  <h2 contenteditable>本次交流聚焦三个议题</h2>
  <div class="cols3">
    <div class="card"><div class="card-title" contenteditable>① 行业演进方向</div>
      <p contenteditable>竞争维度由「可否检出」转向「多快检出」</p>
      <p contenteditable>试剂形态由冷链液态转向冻干，形态决定可覆盖市场</p>
      <p contenteditable>NA 残留控制由加分项转为准入门槛</p></div>
    <div class="card"><div class="card-title" contenteditable>② 宝锐能力对应</div>
      <p contenteditable>快速：qRT-PCR 用时低至 20min</p>
      <p contenteditable>冻干：25℃ 常温放置 18 个月</p>
      <p contenteditable>NA 控制：&lt;8×10⁻⁴ copies/U</p></div>
    <div class="card"><div class="card-title" contenteditable>③ 项目对接路径</div>
      <p contenteditable>按官方推荐体系选型，货号与测试方案直接对应</p>
      <p contenteditable>样品与测试方案同步交付</p>
      <p contenteditable>支持委托冻干与联合开发</p></div>
  </div>'''))
P.append(('content', '''
  <div class="kicker">CONTENTS</div>
  <h2 contenteditable>目录</h2>
  <div class="toc">
    <div class="toc-row"><span class="num">01</span><span class="toc-title" contenteditable>行业热点</span><span class="toc-desc" contenteditable>9 项行业变化 · 痛点归集 · 选型框架</span></div>
    <div class="toc-row"><span class="num">02</span><span class="toc-title" contenteditable>关于宝锐</span><span class="toc-desc" contenteditable>公司 · 历程 · 荣誉 · 质量 · 制造 · 研发 · 冻干 · 服务</span></div>
    <div class="toc-row"><span class="num">03</span><span class="toc-title" contenteditable>四个特色能力</span><span class="toc-desc" contenteditable>快速 · 冻干全预混 · NA 控制 · 抗抑制</span></div>
    <div class="toc-row"><span class="num">04</span><span class="toc-title" contenteditable>产品矩阵</span><span class="toc-desc" contenteditable>官方推荐体系表，与货号逐一对应</span></div>
    <div class="toc-row"><span class="num">05</span><span class="toc-title" contenteditable>合作方式</span><span class="toc-desc" contenteditable>三种合作方式 · 四步落地流程</span></div>
  </div>'''))
P.append(('section', '''
  <div class="secnum">01</div>
  <h1 contenteditable>行业趋势与变化</h1>
  <p class="sub" contenteditable>9 项行业热点，归集为三个议题</p>'''))

# 热点页（5页，两栏）
trends = [
  ('HOT TREND 01', '快速化：30 分钟内完成检测',
   ['需求侧：一体机与 POCT 以周转时间为核心卖点，扩增环节时间被压缩至最短', '技术侧：快速酶与快速缓冲体系协同', '结论：酶、缓冲体系与扩增程序三者协同'],
   ['qRT-PCR 检测用时低至 10 min', '扩增速率不低于 1kb/5s', '快速体系：FM2181-4 / FMD5104 等', '可按贵司仪器与扩增程序做适配调试']),
  ('HOT TREND 02', '全预混与冻干化：免除冷链依赖',
   ['基层、海外与应急场景难以承担冷链成本', '指标升级：由 4℃ 稳定提升至常温长期稳定', '形态决定市场边界：冻干球可覆盖无冷链条件客户'],
   ['可冻干原料 25℃ 常温放置 18 个月', '抗吸湿：敞口 4h 后 55℃ 加速 30d 达标', '冻干形态：八联管/西林瓶/冻干球', '提供委托冻干服务与全套仪器']),
  ('HOT TREND 03', 'NA 控制成为准入门槛',
   ['NA 残留定义：宿主核酸与外源基因组导致假阳、起线与注册申报受阻', '驱动因素：多重与高灵敏项目、注册申报对 0 起线要求持续收紧', '客户痛点：研发阶段可复现，量产批次出现起线'],
   ['NA 级货号：酶与预混体系全覆盖', '宿主核酸残留 &lt;8×10⁻⁴ copies/U', 'NTC 47 复管阴性，覆盖 8 类条件致病菌/真菌', '可提供出库检测口径供你复核']),
  ('HOT TREND 05-06', '多重扩增 + 复杂样本直扩',
   ['单靶标向 3–10 重扩展：引物探针、Mg²⁺ 与退火温度相互制约', '两条技术路线：多色荧光探针法与熔解曲线法（MMCA）', '直扩价值：省去提取耗材，缩短 20–40 分钟'],
   ['多重货号：FM2181-4 / FMD5071-4-DB；MMCA FM0301 / FM8254-TP', '4 通道 4 靶标多重场景已验证', '直扩加样：全血≤5% · 血浆血清≤30% · 唾液≤2μL · 粪便≤0.5%', '直扩货号：FMD2011 / FMD2021 / FMD2111-DB']),
  ('HOT TREND 09', '分子诊断流水线：从单机到全自动',
   ['2026-09 国家药监局批准「全自动核酸检测分析系统」上市：单台仪器内完成 试剂制备 → 核酸提取 → PCR 全流程',
    '约 8 小时自动完成多达 448 项检测；占地小、集成度高，内部按 PCR 实验室逻辑划分为三个模块',
    '头部厂商由免疫诊断延伸至分子诊断，形成免疫 + 生化 + 分子全场景布局；分子检测由单机走向流水线，试剂须满足「上机即用」要求'],
   ['支持按仪器板位与排列做预封装（48T / 64T 等分装形态）',
    '三种交付形态：全预混 / 单管全预混 / 全拆分，适配不同上机方式',
    '可冻干原料 25℃ 常温 18 个月；冻干球 / 八联管 / 西林瓶',
    '批间一致：三段把关 + 9 套洁净车间；含免提取直扩 FMD2011 / FMD2021 / FMD5104-4-TP / FMD5124-TP']),
  ('HOT TREND 04·07·08', '一致性 · 出海 · 国产替代',
   ['流水线上线后：原料批间波动将直接导致整线返工', '出海合规：无法获得原料方技术文件时需自行建立验证', '国产替代：竞争关键在批间一致性，而非单次性能'],
   ['三段把关 + 9 套洁净车间', 'ISO9001（2018）· ISO13485（2024）', '2012 成立 · 国家小巨人 · 2.6 万㎡ 总部园区']),
]
for kicker, title, left, right in trends:
    li = ''.join(f'<p contenteditable>{t}</p>' for t in left)
    ri = ''.join(f'<p contenteditable>{t}</p>' for t in right)
    P.append(('content', f'''
  <div class="kicker">{kicker}</div>
  <h2 contenteditable>{title}</h2>
  <div class="twocol">
    <div class="col"><div class="col-label">行业趋势</div>{li}</div>
    <div class="col col-tint"><div class="col-label">宝锐对应能力</div>{ri}</div>
  </div>'''))

# 痛点收口 + 选型尺
P.append(('content', '''
  <div class="kicker">PAIN POINTS</div>
  <h2 contenteditable>当前三大核心痛点</h2>
  <div class="cols3">
    <div class="card"><div class="card-title" contenteditable>① 快速化推进受阻</div><p contenteditable>循环时间难以压缩 / 更换快速酶后仍偏慢 / 提速伴随灵敏度下降</p></div>
    <div class="card"><div class="card-title" contenteditable>② 冷链与冻干工艺受阻</div><p contenteditable>冻干后活性衰减 / 常温指标难以承诺 / 稳定期不达标</p></div>
    <div class="card"><div class="card-title" contenteditable>③ NA 残留控制超标</div><p contenteditable>批量起线 / 排查周期长 / 注册申报受阻</p></div>
  </div>
  <div class="conclusion" contenteditable>上述三项痛点，与第 3 章的四项特色能力一一对应</div>'''))
P.append(('content', '''
  <div class="kicker">SELECTION RULER</div>
  <h2 contenteditable>选型决策的三个维度</h2>
  <div class="ruler">
    <div class="ruler-row"><span class="num">①</span><b contenteditable>体系形态</b><span contenteditable>液体 / 全预混 / 冻干球 —— 终端是否具备冷链条件</span></div>
    <div class="ruler-row"><span class="num">②</span><b contenteditable>性能边界</b><span contenteditable>速度 / 耐抑制 / NA 控制 / 多重 —— 关键指标瓶颈所在</span></div>
    <div class="ruler-row"><span class="num">③</span><b contenteditable>合作深度</b><span contenteditable>标准品 / 委托冻干 / 联合开发 —— 采购供货或共同开发</span></div>
  </div>
  <div class="conclusion" contenteditable>选型顺序：形态 → 性能 → 货号</div>'''))

# 02 章
P.append(('section', '''
  <div class="secnum">02</div>
  <h1 contenteditable>关于宝锐</h1>
  <p class="sub" contenteditable>公司 · 历程 · 荣誉 · 质量 · 制造 · 研发 · 冻干 · 服务</p>'''))
P.append(('content', '''
  <div class="kicker">WHO WE ARE</div>
  <h2 contenteditable>公司概况与历程</h2>
  <div class="twocol">
    <div class="col"><div class="col-label">公司概况</div>
      <p contenteditable>2012 年成立，专注为工业与科研客户提供生物原料与试剂解决方案</p>
      <p contenteditable>国家高新技术企业 · 国家专精特新"小巨人"</p>
      <p contenteditable>9 套符合 GMP 要求的洁净车间</p>
      <p contenteditable>2.6 万㎡ 总部园区（2026 年投用）</p></div>
    <div class="col col-tint"><div class="col-label">发展历程</div>
      <p contenteditable><b>2012</b> 公司成立</p>
      <p contenteditable><b>2017</b> 国家高新技术企业认定</p>
      <p contenteditable><b>2022</b> 国家专精特新"小巨人"</p>
      <p contenteditable><b>2024</b> 通过 ISO13485</p>
      <p contenteditable><b>2026</b> 2.6 万㎡ 总部园区投用</p></div>
  </div>'''))
P.append(('content', '''
  <div class="kicker">HONOR &amp; QUALITY</div>
  <h2 contenteditable>荣誉与质量体系</h2>
  <div class="twocol">
    <div class="col"><div class="col-label">企业荣誉</div>
      <p contenteditable>国家高新技术企业（2017）· 国家专精特新"小巨人"（2022）</p>
      <p contenteditable>广东省专精特新企业（2021）· 省分子诊断原料酶工程中心（2023）</p>
      <p contenteditable>省博士后创新实践基地（2024）</p>
      <p contenteditable>ISO9001（2018）· ISO13485（2024）</p></div>
    <div class="col col-tint"><div class="col-label">质量体系</div>
      <p contenteditable>三段把关：入库检测 → 生产控制 → 出库质检</p>
      <p contenteditable>客诉闭环：响应 → 排查 → 定位 → 关闭与预防</p>
      <p contenteditable>满意度 ≥90 分 · 一次合格率 ≥95% · 投诉 ≤3%</p></div>
  </div>'''))
P.append(('content', '''
  <div class="kicker">CAPABILITY</div>
  <h2 contenteditable>制造 · 研发 · 冻干 · 服务</h2>
  <div class="cols4">
    <div class="card"><div class="card-title" contenteditable>制造</div><p contenteditable>工程菌株 → 自动化发酵 → 精细纯化 → 修饰 → 配制 → 售后</p><p class="note" contenteditable>三级种子库 + 高密度发酵 + 精细纯化 = 批间一致性</p></div>
    <div class="card"><div class="card-title" contenteditable>研发平台</div><p contenteditable>MTPS 微孔板筛选 / MHTS 高通量 10⁷/day / CARD 理性设计+机器学习</p><p class="note" contenteditable>Taq、MMLV 热稳定性与活性提升约一个数量级</p></div>
    <div class="card"><div class="card-title" contenteditable>冻干</div><p contenteditable>八联管 / 西林瓶 / 冻干球（含彩色）</p><p class="note" contenteditable>25℃ 18 个月 · 提供委托冻干服务与全套仪器</p></div>
    <div class="card"><div class="card-title" contenteditable>服务</div><p contenteditable>研发对研发对接 · 样品与测试方案同步交付 · 快速响应 · 定制开发</p><p class="note" contenteditable>常规货号 1 周内寄出</p></div>
  </div>'''))

# 03 章 四特色
P.append(('section', '''
  <div class="secnum">03</div>
  <h1 contenteditable>四个特色能力</h1>
  <p class="sub" contenteditable>快速 · 冻干全预混 · NA 控制 · 抗抑制</p>'''))
caps = [
  ('CAPABILITY 01', '特色 1 · 快速扩增', 'qRT-PCR 检测用时低至 20 min（官方口径）',
   ['qRT-PCR 用时低至 20 min', '扩增速率不低于 1kb/10s', '快速 qPCR：FM2181-4', '快速 qRT-PCR：FM5144-TP', 'MMCA：FM0301 / FM8254-TP'],
   ['适用场景：一体机 / POCT', '终端客户重点关注周转时间', '客户现状：已更换快速酶，但灵敏度稳定性不足']),
  ('CAPABILITY 02', '特色 2 · 冻干与全预混', '可冻干原料 25℃ 常温放置 18 个月（真空密封）',
   ['25℃ 常温放置 18 个月（真空密封）', '抗吸湿：敞口 4h 后 55℃ 加速 30d', '八联管 / 西林瓶 / 冻干球', '可冻干：FM2181-4 / FMD5071-4-DB', '预冻干：FM5144-TP / FMD5084-4-TP'],
   ['目标市场：无冷链条件地区', '客户诉求：免除配液与分装环节', '产品需支持常温运输']),
  ('CAPABILITY 03', '特色 3 · NA 控制', '宿主核酸残留 &lt;8×10⁻⁴ copies/U',
   ['NA 级货号：酶与预混体系全覆盖', '出库质量标准含污染控制项', 'E.coli DNA 线性 R²=0.999', 'NTC 47 复管阴性，覆盖 8 类致病菌/真菌'],
   ['"常见质询：如何证明达到 NA 级？"', '→ 47 复管 NTC 全阴', '→ + 残留 &lt;8×10⁻⁴ copies/U', '→ + 线性 R²=0.999']),
  ('CAPABILITY 04', '特色 4 · 抗抑制与复杂样本', '血 / 拭子 / 组织匀浆 / 粪便样本可直扩',
   ['全血 ≤5%、血浆/血清 ≤30%', '唾液 ≤2 μL、粪便 ≤0.5%', '耐抑制酶（抗体/适配体修饰）', 'Mg²⁺ 与缓冲体系重新配比 + 程序协同优化', '配套 AS17 全血释放剂'],
   ['适用场景：动物诊断 / 宠物 / 畜牧检测', '适用场景：基层快检与免提取方案', '你被"更换样本类型即失效"卡住过']),
]
for kicker, title, concl, data, fit in caps:
    di = ''.join(f'<p contenteditable>{t}</p>' for t in data)
    fi = ''.join(f'<p contenteditable>{t}</p>' for t in fit)
    P.append(('content', f'''
  <div class="kicker">{kicker}</div>
  <h2 contenteditable>{title}</h2>
  <div class="conclusion" contenteditable>{concl}</div>
  <div class="twocol">
    <div class="col"><div class="col-label">结论级数据与货号</div>{di}</div>
    <div class="col col-tint"><div class="col-label">适用场景</div>{fi}</div>
  </div>'''))

# 04 章 产品矩阵
P.append(('section', '''
  <div class="secnum">04</div>
  <h1 contenteditable>产品矩阵</h1>
  <p class="sub" contenteditable>官方推荐体系表，货号按官方口径对应</p>'''))
P.append(('content', '''
  <div class="kicker">PRODUCT MAP</div>
  <h2 contenteditable>产品全景：按场景选型</h2>
  <div class="table">
    <div class="trow"><span class="num">①</span><b contenteditable>多重快速扩增</b><span contenteditable>DNA 2×/RNA 5×/2× SensiDirect</span><em contenteditable>FM2181-4 / FM5144-TP / MD2104-X</em></div>
    <div class="trow"><span class="num">②</span><b contenteditable>多重熔解曲线 MMCA</b><span contenteditable>2×/3×/8× 多重预混</span><em contenteditable>FM2181-4 / FM0301 / FM8254-TP</em></div>
    <div class="trow"><span class="num">③</span><b contenteditable>DNA·RNA 单管</b><span contenteditable>2× 单管全预混系列</span><em contenteditable>FM5071-DB / FMD5071-4-DB / FM2181-4-X</em></div>
    <div class="trow"><span class="num">④</span><b contenteditable>直扩（免提取）</b><span contenteditable>DNA/RNA/粪便专用</span><em contenteditable>FMD2011 / FMD5084-4-TP / FMD2111-DB</em></div>
    <div class="trow"><span class="num">⑤</span><b contenteditable>Tth 恒温/反转录</b><span contenteditable>Hyperstart Tth</span><em contenteditable>E10-000725</em></div>
  </div>
  <div class="conclusion" contenteditable>选型顺序：场景 → 体系形态 → 性能档 → 货号</div>'''))
P.append(('content', '''
  <div class="kicker">PART NUMBERS</div>
  <h2 contenteditable>体系货号速查</h2>
  <div class="table">
    <div class="trow"><span class="num">①</span><b contenteditable>多重快速扩增</b><span contenteditable>扩增 ≥1kb/10s；最快 30min；更适合多重</span></div>
    <div class="trow"><span class="num">②</span><b contenteditable>MMCA 熔解曲线</b><span contenteditable>探针法熔解曲线分型（HPV 分型）、呼吸道多重</span></div>
    <div class="trow"><span class="num">③</span><b contenteditable>DNA / RNA 单管</b><span contenteditable>单管 + 免提取/快速；POCT 场景</span></div>
    <div class="trow"><span class="num">④</span><b contenteditable>直扩（免提取）</b><span contenteditable>血/唾液/粪便各一支；全血≤5%、唾液≤2μL</span></div>
    <div class="trow"><span class="num">⑤</span><b contenteditable>Tth 试剂</b><span contenteditable>耐抑制、可多靶标；复杂样本 + 高灵敏 RNA 检测</span></div>
  </div>
  <div class="conclusion" contenteditable>完整货号表见《产品推荐清单》，可按项目直接对应</div>'''))

# 05 章
P.append(('content', '''
  <div class="kicker">COOPERATION</div>
  <h2 contenteditable>合作方式</h2>
  <div class="cols3">
    <div class="card"><div class="card-title" contenteditable>① 标准品供货</div><p contenteditable>按货号直接采购，常规货期与装量</p></div>
    <div class="card"><div class="card-title" contenteditable>② 委托冻干 / 定制</div><p contenteditable>工艺与产线协同，含小批试产与稳定性验证</p></div>
    <div class="card"><div class="card-title" contenteditable>③ 联合开发</div><p contenteditable>共同定义指标与节点，面向注册申报与长周期平台</p></div>
  </div>
  <div class="steps">
    <div class="step"><b contenteditable>① 需求确认</b><span contenteditable>样本/仪器/指标/时间节点</span></div>
    <div class="step"><b contenteditable>② 样品测试</b><span contenteditable>寄样与测试方案，1 周内寄出</span></div>
    <div class="step"><b contenteditable>③ 小批验证</b><span contenteditable>小批试产+稳定性+批间差</span></div>
    <div class="step"><b contenteditable>④ 量产/委托/联合</b><span contenteditable>进入长期供货或深度合作</span></div>
  </div>'''))
P.append(('ending', '''
  <h1 contenteditable>体系交予宝锐<br>时间留给您的团队</h1>
  <p class="sub" contenteditable>后续事项：① 寄送样品　② 安排技术交流　③ 发送《产品推荐清单》</p>
  <div class="qrs">
    <div class="qr"><img src="data:image/png;base64,__QRWX__"><span contenteditable>公众号</span></div>
    <div class="qr"><img src="data:image/png;base64,__QRXHS__"><span contenteditable>小红书</span></div>
    <div class="qr"><img src="data:image/png;base64,__QRSPH__"><span contenteditable>视频号</span></div>
  </div>
  <div class="contact" contenteditable>珠海宝锐生物科技有限公司<br>电话 0756-8699969　|　邮箱 marketing@biori.com　|　网址 www.biori.com　|　地址 珠海市香洲区水岸一路88号</div>'''))

import base64
def b64(p):
    return base64.b64encode(open(p, 'rb').read()).decode()

logo = b64('/Users/liuxinyuan/work/公司资料/logo_transparent.png')
qrwx = b64('/Users/liuxinyuan/Desktop/Hermes输出-工作类/对外物料/客户宣讲_20260921/qr_wx.png')
qrxhs = b64('/Users/liuxinyuan/Desktop/Hermes输出-工作类/对外物料/客户宣讲_20260921/qr_xhs.png')
qrsph = b64('/Users/liuxinyuan/Desktop/Hermes输出-工作类/对外物料/客户宣讲_20260921/qr_sph.png')

TOPBAR = ('<div class="topbar"><div class="logo"></div>'
          '<div class="slogan">守护生命健康，缔造美好生活</div></div>')
slides = []
for i, (typ, html) in enumerate(P, 1):
    html = html.replace('__LOGO__', logo).replace('__QRWX__', qrwx).replace('__QRXHS__', qrxhs).replace('__QRSPH__', qrsph)
    cls = {'cover': 'cover', 'section': 'section', 'ending': 'ending'}.get(typ, '')
    slides.append(f'<section class="slide {cls}" id="s{i}" data-page="{i}">{TOPBAR}{html}</section>')

css = '''
*{margin:0;padding:0;box-sizing:border-box}
:root{--logo:url('data:image/png;base64,__LOGO__');
  --fnt:"Microsoft YaHei","PingFang SC","Helvetica Neue",Arial,sans-serif;
  --blue:#002FA7;--ink:#0a0a0a;--ink2:#333;--grey:#6e6e73;--tint:#f5f5f7;
  /* ── 字阶：全篇 7 级，同类型文字必定同字号同字重（改这一处即全局生效）──
     hero 封面主标题 / sec 章节页主标题 / h2 页面主标题 / h3 卡片·小标题
     sub 副标题·导语 / body 正文 / note 注释·图注·页脚·导航 */
  --t-hero:min(8.6vw,11.6vh);
  --t-sec:min(6.6vw,9.2vh);
  --t-h2:min(3.75vw,6.1vh);
  --t-h3:min(1.9vw,3.05vh);
  --t-sub:min(2vw,3.4vh);
  --t-body:min(1.38vw,2.26vh);
  --t-note:min(1.16vw,2vh);
  --t-label:min(1.05vw,1.72vh);
  --t-bar:17px;
  --lh-head:1.1;--lh-body:1.62;
}
body{font-family:var(--fnt);background:#0a0a0a;overflow:hidden;-webkit-font-smoothing:antialiased}
#deck{position:relative;width:100vw;height:100vh}
.slide{position:absolute;inset:0;display:none;background:#fff;color:var(--ink);padding:calc(90px + 3vh) 5vw 3vh;flex-direction:column;justify-content:flex-start}
.slide.active{display:flex}
.slide.cover,.slide.section,.slide.ending{background:var(--blue);color:#fff}
.topbar{position:absolute;top:0;left:0;right:0;height:90px;background:#fff;display:flex;align-items:center;padding:0 5vw;gap:0;border-bottom:1px solid rgba(10,10,10,.18);z-index:5}
.logo{height:68px;width:201px;background-image:var(--logo);background-size:contain;background-repeat:no-repeat;background-position:left center}
.slogan{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);font-size:var(--t-bar);letter-spacing:.22em;color:var(--blue);font-weight:600;white-space:nowrap;text-align:center}
.kicker{color:var(--blue);letter-spacing:.22em;font-size:var(--t-label);margin-bottom:1.6vh;font-weight:600}
.slide.cover .kicker,.slide.section .kicker,.slide.ending .kicker{color:rgba(255,255,255,.8)}
h1{font-size:var(--t-hero);font-weight:200;line-height:var(--lh-head);letter-spacing:-.02em}
h2{font-size:var(--t-h2);font-weight:400;line-height:var(--lh-head);margin-bottom:1.9vh;letter-spacing:-.01em}
.sub{font-size:var(--t-sub);font-weight:300;opacity:.88;margin-top:1.8vh;max-width:60ch;line-height:1.5}
.footline{position:absolute;bottom:4vh;left:5vw;opacity:.72;font-size:var(--t-note)}
.secnum{position:absolute;top:calc(90px + 2vh);left:5vw;font-size:24vh;font-weight:200;opacity:.15;line-height:1}
.slide.section h1{position:absolute;top:38vh;font-size:var(--t-sec)}
.slide.section .sub{position:absolute;top:54vh}
/* ── 封面：左侧蓝色竖条 + 标题块栅格 ── */
.cover-body{display:flex;gap:2.6vw;margin-top:6vh}
.cover-rule{width:6px;background:#fff;opacity:.92}
.cover-main{flex:1}
.cover-hr{height:1px;background:rgba(255,255,255,.5);margin:4.4vh 0 0}
.slide.cover .kicker{margin-bottom:3.2vh}
.slide.cover .sub{margin-top:4vh}
.slide.cover .footline{bottom:6.6vh;left:auto;right:5vw;text-align:right}
.cols3,.cols4{display:grid;gap:2vw;margin-top:3vh;flex:1}
.cols3{grid-template-columns:repeat(3,1fr)}
.cols4{grid-template-columns:repeat(4,1fr)}
.card{background:var(--tint);padding:2.2vh 1.8vw;border-top:6px solid var(--blue)}
.card-title{font-size:var(--t-h3);font-weight:600;margin-bottom:1.6vh;line-height:1.3}
.card p{font-size:var(--t-body);line-height:var(--lh-body);color:var(--ink2);margin-bottom:.35vh}
.card .note{color:var(--grey);font-size:var(--t-note);margin-top:1vh}
.twocol{display:grid;grid-template-columns:1fr 1fr;gap:2vw;flex:1;margin-top:2vh}
.col{padding:1.6vh 1.4vw}
.col-tint{background:var(--tint)}
.col-label{color:var(--blue);font-weight:600;font-size:var(--t-label);letter-spacing:.14em;margin-bottom:1.8vh}
.col p{font-size:var(--t-body);line-height:1.68;color:var(--ink2);margin-bottom:.8vh}
.conclusion{color:var(--blue);font-size:var(--t-h3);font-weight:600;margin:1.4vh 0}
.ruler .ruler-row{background:var(--tint);padding:1.7vh 1.4vw;margin-bottom:1vh;display:flex;align-items:baseline;gap:1vw;font-size:var(--t-body)}
.ruler .num{color:var(--blue);font-weight:700}
.table{flex:1;margin-top:2vh}
.trow{background:var(--tint);padding:1.6vh 1.4vw;margin-bottom:.9vh;display:flex;align-items:baseline;gap:1.2vw;font-size:var(--t-body);line-height:1.5}
.trow .num{color:var(--blue);font-weight:700}
.trow b{flex:0 0 auto}
.trow span{color:var(--grey);flex:1 1 auto}
.trow em{color:var(--ink);font-style:normal;margin-left:auto;flex:0 0 auto}
.steps{display:grid;grid-template-columns:repeat(4,1fr);gap:1.5vw;margin-top:2vh}
.step{background:var(--tint);padding:1.6vh 1vw}
.step b{display:block;font-size:var(--t-h3);margin-bottom:1vh;line-height:1.35}
.step span{color:var(--grey);font-size:var(--t-note);line-height:1.6}
.qrs{display:flex;gap:6vw;justify-content:center;margin-top:4vh}
.qr{text-align:center}
.qr img{width:150px;height:150px;background:#fff}
.qr span{display:block;color:#fff;margin-top:1.5vh;font-size:var(--t-note)}
.contact{margin-top:4vh;line-height:1.9;font-size:var(--t-body);opacity:.9}
/* ── 目录：栅格对齐 + 宽松行距（此前无样式，挤在浏览器默认行距上）── */
.toc{display:flex;flex-direction:column;flex:1;justify-content:center;margin-top:3vh}
.toc-row{display:grid;grid-template-columns:4.4ch 21ch 1fr;align-items:baseline;gap:2vw;
         padding:2.7vh 0;border-bottom:1px solid rgba(10,10,10,.13)}
.toc-row:first-child{border-top:1px solid rgba(10,10,10,.13)}
.toc-row .num{font-size:var(--t-note);font-weight:700;color:var(--blue);letter-spacing:.12em}
.toc-title{font-size:var(--t-h3);font-weight:600}
.toc-desc{font-size:var(--t-body);color:var(--grey);line-height:1.5}
[contenteditable]{outline:none;border-radius:2px;transition:background .15s}
[contenteditable]:hover{background:rgba(0,47,167,.08);cursor:text}
[contenteditable]:focus{background:rgba(0,47,167,.12)}
#nav{position:fixed;bottom:2vh;right:3vw;z-index:99;color:#fff;background:rgba(0,0,0,.5);padding:8px 14px;border-radius:20px;font-size:var(--t-note)}
#hint{position:fixed;bottom:2vh;left:3vw;z-index:99;color:rgba(255,255,255,.7);font-size:var(--t-note)}
button.editmode{position:fixed;top:calc(90px + 1.2vh);right:3vw;z-index:99;opacity:.42;transition:opacity .2s;}button.editmode:hover{opacity:1}
button.editmode{background:rgba(0,47,167,.9);color:#fff;border:none;padding:8px 16px;border-radius:20px;font-size:var(--t-note);cursor:pointer}
'''

js = '''
let cur = 1, total = document.querySelectorAll('.slide').length;
function show(n){
  document.querySelectorAll('.slide').forEach(s=>s.classList.remove('active'));
  const el = document.getElementById('s'+n);
  if(el) el.classList.add('active');
  cur = n;
  document.getElementById('nav').textContent = n + ' / ' + total;
}
function next(){ if(cur<total) show(cur+1); }
function prev(){ if(cur>1) show(cur-1); }
document.addEventListener('keydown', e=>{
  if(e.target && e.target.getAttribute('contenteditable')!==null && ['ArrowLeft','ArrowRight'].includes(e.key)) return; // 编辑时方向键不翻页
  if(e.key==='ArrowRight'||e.key==='PageDown') next();
  if(e.key==='ArrowLeft'||e.key==='PageUp') prev();
  if(e.key==='Home') show(1);
  if(e.key==='End') show(total);
  if(e.key==='Escape'){ document.getElementById('overview').classList.toggle('show'); }
});
let wheelLock=false;
document.addEventListener('wheel', e=>{
  if(e.target && e.target.getAttribute('contenteditable')!==null) return;
  if(wheelLock) return;
  wheelLock=true; setTimeout(()=>wheelLock=false, 600);
  if(e.deltaY>0) next(); else prev();
}, {passive:true});
// 总览
const ov = document.createElement('div');
ov.id='overview'; ov.style.cssText='position:fixed;inset:0;background:rgba(0,0,0,.85);display:none;z-index:200;grid-template-columns:repeat(5,1fr);gap:2vw;padding:5vh 5vw;overflow:auto';
document.body.appendChild(ov);
document.querySelectorAll('.slide').forEach(s=>{
  const d=document.createElement('div');
  d.textContent=s.dataset.page; d.style.cssText='background:#fff;height:14vh;display:flex;align-items:center;justify-content:center;font-size:3vh;color:#0a0a0a;border-radius:6px;cursor:pointer';
  d.onclick=()=>{ show(+s.dataset.page); ov.style.display='none'; ov.classList.remove('show'); };
  ov.appendChild(d);
});
// 编辑模式切换
const eb=document.createElement('button'); eb.className='editmode'; eb.textContent='编辑模式：开';
let editOn=false;
eb.onclick=()=>{
  editOn=!editOn;
  document.querySelectorAll('[contenteditable]').forEach(e=>e.setAttribute('contenteditable', editOn?'true':'false'));
  eb.textContent='编辑模式：'+(editOn?'开':'关');
};
document.body.appendChild(eb);
const nav=document.createElement('div'); nav.id='nav'; document.body.appendChild(nav);
const hint=document.createElement('div'); hint.id='hint'; hint.textContent='← → 翻页 · ESC 总览 · 点击文字直接编辑'; document.body.appendChild(hint);
show(1);
'''

html = f'''<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>宝锐诊断原料 · 客户宣讲（瑞士风 · 可编辑）</title>
<style>{css}</style>
</head>
<body>
<div id="deck">
{chr(10).join(slides)}
</div>
<script>{js}</script>
</body>
</html>'''

# 最终文档兜底替换（head 里的 CSS 变量也含占位符，不能只替换每页正文）
html = html.replace('__LOGO__', logo).replace('__QRWX__', qrwx).replace('__QRXHS__', qrxhs).replace('__QRSPH__', qrsph)
open(OUT, 'w').write(html)
print('HTML 生成:', OUT, len(html), 'bytes,', len(slides), '页')
