from pptx import Presentation
from pptx.util import Inches, Pt
from pptx.enum.shapes import MSO_SHAPE
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
from pptx.dml.color import RGBColor
from pptx.enum.dml import MSO_THEME_COLOR
from pathlib import Path
import math, datetime

OUT = Path('/Users/bot1/Volumes/root_for_ai/AI工作区/通用_PPT_公司简介taste测试_20260606_0052/deliverables/taste_skill_公司简介三风格测试_9页.pptx')

prs = Presentation()
prs.slide_width = Inches(13.333)
prs.slide_height = Inches(7.5)
# remove default? python-pptx starts blank no slides.

W, H = 13.333, 7.5

def rgb(hexstr):
    hexstr = hexstr.strip('#')
    return RGBColor(int(hexstr[0:2],16), int(hexstr[2:4],16), int(hexstr[4:6],16))

def blank():
    return prs.slide_layouts[6]

def add_bg(slide, color):
    slide.background.fill.solid()
    slide.background.fill.fore_color.rgb = rgb(color)

def add_text(slide, text, x, y, w, h, size=18, color='111111', bold=False, font='Aptos', align='left', valign='top', line_spacing=None):
    tx = slide.shapes.add_textbox(Inches(x), Inches(y), Inches(w), Inches(h))
    tf = tx.text_frame
    tf.clear()
    tf.margin_left = Inches(0)
    tf.margin_right = Inches(0)
    tf.margin_top = Inches(0)
    tf.margin_bottom = Inches(0)
    tf.vertical_anchor = {'top': MSO_ANCHOR.TOP, 'mid': MSO_ANCHOR.MIDDLE, 'bottom': MSO_ANCHOR.BOTTOM}.get(valign, MSO_ANCHOR.TOP)
    p = tf.paragraphs[0]
    p.alignment = {'left': PP_ALIGN.LEFT, 'center': PP_ALIGN.CENTER, 'right': PP_ALIGN.RIGHT}.get(align, PP_ALIGN.LEFT)
    run = p.add_run()
    run.text = text
    run.font.size = Pt(size)
    run.font.bold = bold
    run.font.name = font
    run.font.color.rgb = rgb(color)
    if line_spacing:
        p.line_spacing = line_spacing
    return tx

def add_rect(slide, x, y, w, h, fill, line=None, radius=False, transparency=0):
    shp = slide.shapes.add_shape(MSO_SHAPE.ROUNDED_RECTANGLE if radius else MSO_SHAPE.RECTANGLE, Inches(x), Inches(y), Inches(w), Inches(h))
    shp.fill.solid()
    shp.fill.fore_color.rgb = rgb(fill)
    shp.fill.transparency = transparency
    if line:
        shp.line.color.rgb = rgb(line)
        shp.line.width = Pt(1)
    else:
        shp.line.fill.background()
    return shp

def add_circle(slide, x, y, d, fill, line=None, transparency=0):
    shp = slide.shapes.add_shape(MSO_SHAPE.OVAL, Inches(x), Inches(y), Inches(d), Inches(d))
    shp.fill.solid(); shp.fill.fore_color.rgb = rgb(fill); shp.fill.transparency = transparency
    if line:
        shp.line.color.rgb = rgb(line); shp.line.width = Pt(1)
    else:
        shp.line.fill.background()
    return shp

def add_line(slide, x, y, w, h, color, width=1):
    shp = slide.shapes.add_shape(MSO_SHAPE.LINE_INVERSE if False else MSO_SHAPE.RECTANGLE, Inches(x), Inches(y), Inches(w), Inches(h))
    shp.fill.solid(); shp.fill.fore_color.rgb = rgb(color)
    shp.line.fill.background()
    return shp

def footer(slide, style_name, color, bg=None):
    add_text(slide, style_name, 0.65, 7.02, 3.2, 0.2, size=8.5, color=color, font='Aptos', bold=False)
    add_text(slide, 'Taste Skill PPT Test · 2026', 10.25, 7.02, 2.45, 0.2, size=8.5, color=color, font='Aptos', align='right')

# ---------------- Version A: Midnight Executive ----------------
def vA_cover():
    s=prs.slides.add_slide(blank()); add_bg(s,'07111F')
    # large abstract blocks
    add_rect(s, 8.15, -0.4, 5.55, 8.3, '102A43')
    add_circle(s, 9.4, 0.8, 3.8, '1B4965', transparency=10)
    add_circle(s, 10.8, 3.0, 2.2, '5FA8D3', transparency=25)
    add_rect(s, 0.65, 0.62, 1.35, 0.28, 'D7B56D')
    add_text(s, 'VERSION A', 0.65, 1.05, 2.0, 0.28, 10, 'D7B56D', True, 'Aptos', charSpacing if False else 'left')
    add_text(s, '公司简介', 0.62, 1.55, 4.2, 0.75, 42, 'FFFFFF', True, 'Aptos Display')
    add_text(s, 'Company Profile', 0.65, 2.35, 4.8, 0.45, 20, 'B9C7D8', False, 'Georgia')
    add_text(s, '以可信赖的产品、设计与数字化能力，帮助客户把复杂业务变成可落地的增长系统。', 0.67, 3.25, 5.5, 1.0, 20, 'EAF1F8', False, 'Aptos')
    # stats bar
    for i,(num,lab) in enumerate([('8+','年行业经验'),('120+','合作项目'),('3','核心能力')]):
        x=0.75+i*1.75
        add_text(s,num,x,5.45,1.2,0.35,28,'FFFFFF',True,'Aptos Display')
        add_text(s,lab,x,5.98,1.3,0.25,10,'9FB4C8',False,'Aptos')
    footer(s,'Midnight Executive', '7B8EA3')

def vA_about():
    s=prs.slides.add_slide(blank()); add_bg(s,'F7F9FC')
    add_rect(s,0,0,13.333,0.55,'07111F')
    add_text(s,'我们是谁',0.65,0.95,3.1,0.5,34,'07111F',True,'Aptos Display')
    add_text(s,'一家面向增长与交付的综合型服务公司',0.67,1.55,4.5,0.35,14,'4C6178',False,'Aptos')
    # left narrative card
    add_rect(s,0.65,2.05,5.0,3.95,'FFFFFF',line='DFE7EF',radius=True)
    add_text(s,'定位',1.05,2.38,1.0,0.3,12,'D7B56D',True,'Aptos')
    add_text(s,'我们把品牌策略、内容设计、技术工具与运营执行放在同一张桌子上，减少沟通损耗，让方案从“好看”走向“可用、可卖、可持续”。',1.05,2.82,4.1,1.3,20,'122238',False,'Aptos')
    add_text(s,'适用于：品牌升级 / 产品上市 / 电商内容 / 数字化工具 / 客户运营',1.05,4.78,4.0,0.35,12,'61758A',False,'Aptos')
    # right 3 pillars
    pillars=[('策略','看清客户、市场与机会'),('设计','建立统一而有记忆点的表达'),('交付','把创意变成可复用资产')]
    for i,(t,d) in enumerate(pillars):
        y=2.05+i*1.25
        add_rect(s,6.25,y,5.95,0.95,'07111F' if i==0 else 'FFFFFF',line='DFE7EF',radius=True)
        add_circle(s,6.55,y+0.24,0.45,'D7B56D' if i==0 else 'DDEAF4')
        add_text(s,str(i+1),6.69,y+0.32,0.18,0.16,10,'07111F',True,'Aptos',align='center')
        add_text(s,t,7.18,y+0.18,1.0,0.25,17,'FFFFFF' if i==0 else '07111F',True,'Aptos')
        add_text(s,d,7.18,y+0.55,3.5,0.22,11,'B9C7D8' if i==0 else '5B6F83',False,'Aptos')
    footer(s,'Midnight Executive', '71849A')

def vA_capabilities():
    s=prs.slides.add_slide(blank()); add_bg(s,'07111F')
    add_text(s,'核心能力',0.65,0.75,3.2,0.55,34,'FFFFFF',True,'Aptos Display')
    add_text(s,'从洞察到资产，再到增长复盘',0.67,1.35,3.8,0.32,13,'9FB4C8')
    cards=[('01','品牌与内容策略','竞品拆解、卖点结构、客户旅程、内容框架'),('02','视觉设计与资产生产','PPT、详情页、包装、视觉模板、活动物料'),('03','数字化与自动化','轻量系统、数据报表、AI 工作流、内部工具')]
    for i,(n,t,d) in enumerate(cards):
        x=0.75+i*4.05
        add_rect(s,x,2.15,3.55,3.8,'0E2136',line='1D3F5F',radius=True)
        add_text(s,n,x+0.3,2.48,0.8,0.35,16,'D7B56D',True,'Georgia')
        add_text(s,t,x+0.3,3.05,2.6,0.6,23,'FFFFFF',True,'Aptos Display')
        add_text(s,d,x+0.3,4.1,2.75,0.7,13,'B9C7D8',False,'Aptos')
        add_rect(s,x+0.3,5.28,1.45,0.08,'D7B56D')
    footer(s,'Midnight Executive', '7B8EA3')

# ---------------- Version B: Eastern Editorial ----------------
def vB_cover():
    s=prs.slides.add_slide(blank()); add_bg(s,'F3EBDD')
    add_rect(s,0.45,0.38,12.45,6.75,'EFE2CE',line='C8AA7A')
    add_circle(s,9.4,0.65,2.7,'C4523D',transparency=8)
    add_circle(s,10.55,1.75,1.45,'D9B06E',transparency=15)
    add_text(s,'纸本东方 / Editorial Warmth',0.8,0.78,3.4,0.28,10,'8B5E34',True,'Songti SC')
    add_text(s,'公司简介',0.85,2.0,4.0,0.8,43,'3A2A1E',True,'Songti SC')
    add_text(s,'以长期主义打磨服务，以审美与方法建立信任。',0.9,3.05,4.65,0.45,18,'684E3A',False,'Kaiti SC')
    add_rect(s,0.9,4.55,3.3,0.04,'A45A3F')
    add_text(s,'策略 · 设计 · 技术 · 运营',0.9,4.85,3.8,0.32,15,'3A2A1E',False,'Songti SC')
    footer(s,'Eastern Editorial', '8B735B')

def vB_about():
    s=prs.slides.add_slide(blank()); add_bg(s,'FBF7EF')
    add_text(s,'关于我们',0.72,0.72,3.2,0.55,34,'3A2A1E',True,'Songti SC')
    add_text(s,'不是把内容堆满，而是让信息有秩序、有呼吸、有记忆点。',0.75,1.33,5.2,0.3,13,'80624A',False,'Kaiti SC')
    add_rect(s,0.72,1.92,4.0,4.55,'EFE2CE',line='D8C2A2')
    add_text(s,'01',1.05,2.25,0.6,0.3,14,'A45A3F',True,'Georgia')
    add_text(s,'我们的角色',1.05,2.75,2.4,0.4,24,'3A2A1E',True,'Songti SC')
    add_text(s,'在品牌方、渠道、供应链和用户之间建立一套清晰表达：既保留质感，也关注效率。',1.05,3.45,2.95,1.2,19,'4A3829',False,'Songti SC')
    # right editorial strips
    items=[('洞察','将市场信息转译成决策语言'),('表达','将品牌优势转译成视觉语言'),('落地','将方案转译成交付资产')]
    for i,(t,d) in enumerate(items):
        y=2.05+i*1.35
        add_rect(s,5.35,y,6.95,0.9,'FFFFFF',line='E4D6C1')
        add_text(s,t,5.75,y+0.21,1.1,0.3,20,'A45A3F',True,'Songti SC')
        add_text(s,d,7.0,y+0.27,3.9,0.25,13,'5A4634',False,'Songti SC')
        add_circle(s,11.65,y+0.28,0.22,'D9B06E')
    footer(s,'Eastern Editorial', '9B826A')

def vB_capabilities():
    s=prs.slides.add_slide(blank()); add_bg(s,'F3EBDD')
    add_text(s,'能力版图',0.72,0.7,3.0,0.55,34,'3A2A1E',True,'Songti SC')
    add_text(s,'三组能力，构成从想法到结果的闭环。',0.75,1.32,3.8,0.28,13,'80624A',False,'Kaiti SC')
    # center big seal
    add_circle(s,5.45,2.05,2.4,'A45A3F',transparency=0)
    add_text(s,'闭环',6.02,2.82,1.1,0.45,25,'F8EFE2',True,'Songti SC',align='center')
    add_text(s,'Capability\nLoop',5.83,3.28,1.5,0.45,10,'F2D3BF',False,'Georgia',align='center')
    nodes=[('策略咨询','定位/卖点/路径',1.05,2.0),('视觉内容','PPT/详情页/包装',8.85,2.0),('数字工具','报表/自动化/AI流程',4.55,5.35)]
    for t,d,x,y in nodes:
        add_rect(s,x,y,3.15,1.1,'FBF7EF',line='D4BE9D')
        add_text(s,t,x+0.25,y+0.18,2.0,0.3,18,'3A2A1E',True,'Songti SC')
        add_text(s,d,x+0.25,y+0.58,2.4,0.23,11,'80624A',False,'Songti SC')
    footer(s,'Eastern Editorial', '8B735B')

# ---------------- Version C: Vibrant Tech ----------------
def vC_cover():
    s=prs.slides.add_slide(blank()); add_bg(s,'F7FBFF')
    add_rect(s,0,0,13.333,7.5,'F7FBFF')
    add_circle(s,9.3,-0.4,4.1,'00A896',transparency=12)
    add_circle(s,10.25,2.15,2.6,'7C3AED',transparency=18)
    add_rect(s,0.72,0.7,1.65,0.34,'111827',radius=True)
    add_text(s,'VERSION C',0.94,0.805,1.2,0.12,8.5,'FFFFFF',True,'Aptos',align='center')
    add_text(s,'公司简介',0.72,1.75,4.0,0.72,44,'111827',True,'Aptos Display')
    add_text(s,'Built for Growth, Designed for Trust.',0.75,2.57,5.4,0.32,18,'00A896',True,'Aptos')
    add_text(s,'用更轻的团队、更快的流程和更清晰的资产系统，支持业务持续迭代。',0.75,3.1,5.4,0.72,19,'384152',False,'Aptos')
    for i,c in enumerate(['00A896','7C3AED','FFB703']):
        add_rect(s,0.78+i*0.42,4.55,0.25,0.25,c,radius=True)
    footer(s,'Vibrant Tech', '6B7280')

def vC_about():
    s=prs.slides.add_slide(blank()); add_bg(s,'FFFFFF')
    add_text(s,'公司画像',0.65,0.68,3.2,0.52,34,'111827',True,'Aptos Display')
    add_text(s,'用产品化方式交付服务，用工具化方式提升效率。',0.67,1.28,4.5,0.28,13,'64748B')
    # dashboard cards
    metrics=[('8+','年经验','00A896'),('120+','项目案例','7C3AED'),('NPS','客户口碑','FFB703')]
    for i,(num,lab,c) in enumerate(metrics):
        x=0.8+i*2.25
        add_rect(s,x,2.0,1.85,1.25,'F8FAFC',line='E2E8F0',radius=True)
        add_text(s,num,x+0.2,2.23,1.1,0.35,26,c,True,'Aptos Display')
        add_text(s,lab,x+0.2,2.82,1.1,0.2,10,'64748B')
    add_rect(s,7.85,1.8,4.55,4.1,'111827',radius=True)
    add_text(s,'我们如何工作',8.25,2.18,2.4,0.3,20,'FFFFFF',True)
    steps=[('Discover','快速梳理问题和资产'),('Design','形成视觉与内容系统'),('Deliver','输出可复用交付物')]
    for i,(t,d) in enumerate(steps):
        y=2.85+i*0.82
        add_circle(s,8.25,y,0.32,['00A896','7C3AED','FFB703'][i])
        add_text(s,str(i+1),8.36,y+0.08,0.1,0.1,8,'111827',True,align='center')
        add_text(s,t,8.78,y-0.02,1.2,0.18,13,'FFFFFF',True)
        add_text(s,d,8.78,y+0.25,2.5,0.18,10,'B8C1CC')
    add_text(s,'“让每一次交付，都沉淀成下一次增长的起点。”',0.85,4.55,5.75,0.55,25,'111827',True,'Aptos Display')
    footer(s,'Vibrant Tech', '6B7280')

def vC_capabilities():
    s=prs.slides.add_slide(blank()); add_bg(s,'0B1020')
    add_circle(s,10.65,0.35,2.7,'00A896',transparency=28)
    add_circle(s,0.6,5.3,1.8,'7C3AED',transparency=20)
    add_text(s,'服务模块',0.72,0.75,3.2,0.52,34,'FFFFFF',True,'Aptos Display')
    add_text(s,'一套适合轻团队的外部能力补给。',0.75,1.35,4.2,0.28,13,'AAB7C8')
    modules=[('Brand Kit','品牌手册、模板、销售话术','00A896'),('Content Lab','详情页、PPT、图文、短视频脚本','7C3AED'),('AI Ops','自动化报表、素材流水线、客服/运营助手','FFB703')]
    for i,(t,d,c) in enumerate(modules):
        y=2.15+i*1.25
        add_rect(s,0.85,y,11.55,0.9,'151C2F',line='253047',radius=True)
        add_rect(s,0.85,y,0.12,0.9,c)
        add_text(s,t,1.25,y+0.18,1.9,0.25,17,'FFFFFF',True,'Aptos Display')
        add_text(s,d,3.45,y+0.24,5.6,0.2,12,'B8C1CC')
        add_text(s,'可按项目 / 月度 / 咨询小时组合',9.65,y+0.25,2.0,0.18,9,c,True,align='right')
    footer(s,'Vibrant Tech', '7D8CA3')

for fn in [vA_cover, vA_about, vA_capabilities, vB_cover, vB_about, vB_capabilities, vC_cover, vC_about, vC_capabilities]:
    fn()

# Core properties
prs.core_properties.title = 'Taste Skill 公司简介三风格测试'
prs.core_properties.subject = '3页公司简介PPT，3个视觉风格版本，共9页'
prs.core_properties.author = 'Hermes Agent'
prs.core_properties.comments = 'Generated as a test of taste-skill + powerpoint workflow.'
prs.save(OUT)
print(OUT)
