const PRODUCT = {
  name: "ChenShu",
  version: "2026",
  downloadUrl: "download.html",
};

const PAYMENT_API_BASE = window.CHENSHU_PAYMENT_API_BASE || "/api/payments/xunhupay";

const PLANS = [
  {
    id: "annual",
    name: "年费版",
    price: 299,
    suffix: "/年",
    badge: "轻量开始",
    summary: "适合个人环评工程师、项目负责人和小型技术团队，用更低成本把本地 AI 工作台放进日常项目流。",
    features: ["本地资料解析与索引", "环评报告与专家意见辅助", "PPT、清单和说明材料生成", "可绑定 2 台设备"],
  },
  {
    id: "lifetime",
    name: "终身版",
    price: 599,
    suffix: "一次付清",
    badge: "推荐",
    summary: "适合长期承接环评项目的用户，一次购买即可长期使用 ChenShu，后续项目复用更划算。",
    features: ["包含年费版全部能力", "永久版本授权", "优先获得行业能力升级", "可绑定 5 台设备"],
  },
];

const productFeatureShowcases = [
  {
    id: "local",
    label: "特性 01",
    tag: "本地化部署",
    title: "项目资料不上云，AI 在本机工作。",
    body: [
      "环评项目资料不是可以随便上传的聊天素材。ChenShu 面向环评项目做本地化部署，可研报告、监测数据、图纸、专家意见和甲方资料，都在你的电脑上解析、检索和生成。",
      "你可以使用 AI 提升效率，但不必把客户资料交给第三方平台处理，降低资料外泄、客户追责和公司信誉受损的风险。",
    ],
    emphasis: "客户资料不应该为了使用 AI 而离开你的电脑。",
    capabilities: ["资料本机解析", "本机检索问答", "本机生成文档", "不上传第三方 AI 平台"],
  },
  {
    id: "knowledge",
    label: "特性 02",
    tag: "项目知识库",
    title: "把散乱资料，变成可追问、可比对、可生成报告的项目知识库。",
    body: [
      "环评报告的质量，不只取决于写得好不好，更取决于项目事实有没有掌握全、对齐准、更新及时。",
      "ChenShu 可以在工程师指令下解析文档、表格、图纸、CAD、会议纪要和专家意见，搭建独立项目知识库，并持续检查数据不一致、资料缺失和版本过时问题。",
    ],
    emphasis: "不用再靠脑子记住整个项目。",
    capabilities: [
      "自动入库：项目资料进入统一事实底座",
      "自动比对：跨资料检查数据冲突和缺失",
      "持续更新：新增意见和图纸后识别旧信息",
      "支撑生成：报告、PPT、回复和整改说明可基于知识库生成",
    ],
  },
  {
    id: "advisor",
    label: "特性 03",
    tag: "顾问与报告生成",
    title: "真正懂环评行业、真正能够写报告的AI工作台。",
    body: [
      "ChenShu 内置环评行业知识大脑，具备图纸解析、行业深度检索和专业文件生成三项专业能力——这不是一个接问题的助手，是一台懂行业的工作台",
    ],
    emphasis: "先把项目事实查清楚，再把专业成果生成出来。",
    capabilities: [
      "行业知识大脑 — 内置环评工程师技能和行业级数据库，法规口径、技术路线、案例判断，不是搜索出来的，是训练进去的",
      "图纸解析能力 — 读懂 CAD、图纸和工程附图，从图形中提取项目参数、核查平面布局，不再需要人工翻图找数据",
      "行业信息深度检索 — 结合行业知识库与网络检索，定位法规依据、标准出处和行业案例，支撑关键结论的专业判断",
      "专业文件生成 — 在工程师指令和确认下生成 Word 报告、汇报 PPT、整改说明和 PDF 材料包，项目资料直接转化为可提交的专业成果",
    ],
  },
  {
    id: "meeting",
    label: "特性 04",
    tag: "会议助手",
    title: "智能生成会议纪要，并为用户提供现场问题的秒级回复建议",
    body: [
      "环评评审会是一场现场质询。ChenShu 实时识别专家提问，调用项目知识库和行业数据库，让你在现场秒速定位依据——不被问住，不乱节奏",
    ],
    emphasis: "",
    capabilities: [
      "实时生成纪要 — 自动识别多人发言，实时生成文字纪要",
      "实时捕捉问题 — 智能识别现场提问，理解问题做好应对",
      "秒速定位依据 — 报告页码、法规条款、项目原文，现场可查",
      "回答建议生成 — 结合知识库和网络检索，提供专业回应思路",
    ],
  },
  {
    id: "drawing",
    label: "特性 05",
    tag: "专业绘图能力",
    badge: "即将推出",
    title: "让 CAD、GIS 和专业图样绘制，变成工程师可调用的本机能力。",
    body: [
      "ChenShu 即将推出 AI 自主专业绘图能力，根据项目资料和工程师指令，辅助完成 CAD 绘制、ArcGIS 图例制作、二维示意图、三维项目图样和汇报图形生成。",
      "过去依赖熟练制图人员才能高效完成的工作，将逐步变成每一位环评工程师都能调用的本机生产力。",
    ],
    emphasis: "让复杂软件听懂工程师的话。",
    capabilities: ["CAD 绘制辅助", "ArcGIS 图例制作", "2D 示意图生成", "3D 项目图样生成", "汇报图形制作"],
  },
];

const scenarioCards = [
  {
    label: "场景 01",
    title: "项目资料进场",
    body: "把报告、附件、监测数据、批复、图件说明等资料放入本地工作区，先梳理资料结构、缺项和待核实问题。",
    result: "减少前期翻文件和找口径的时间。",
  },
  {
    label: "场景 02",
    title: "报告章节辅助",
    body: "围绕工程分析、环境现状、影响识别、预测评价、环保措施等章节，辅助整理要点、草稿和核查清单。",
    result: "让章节推进更连续，少在空白页前消耗精力。",
  },
  {
    label: "场景 03",
    title: "专家意见响应",
    body: "对专家意见、补充说明和修改要求进行拆解，关联本地资料与报告章节，形成可复核的回复思路。",
    result: "让意见响应更清楚、更容易追踪。",
  },
  {
    label: "场景 04",
    title: "汇报与交付准备",
    body: "在用户确认后生成汇报 PPT、问题说明、数据核验清单和会议材料，辅助项目会前准备与交付复查。",
    result: "把临交付前的重复整理变成可控流程。",
  },
];

const workflowSteps = [
  ["01", "资料接入", "导入报告、附件、监测数据、批复、图件说明等本地资料。"],
  ["02", "资料解析", "按项目维度抽取关键信息，识别缺项、冲突和待核实内容。"],
  ["03", "工作流推进", "围绕环评章节和技术路线，协助推进工程分析、环境现状、预测评价和措施论证。"],
  ["04", "成果生成", "在用户确认后生成说明材料、章节草稿、汇报 PPT 或问题回复稿。"],
  ["05", "核验复查", "对数据口径、引用来源、前后表述和专家意见响应进行复核提示。"],
  ["06", "用户定稿", "所有关键判断由用户确认，ChenShu 保持辅助、提醒和执行角色。"],
];

const decisionItems = [
  "是否需要生成报告章节或说明文档",
  "是否安装某个电脑软件依赖",
  "是否生成汇报 PPT 或会议材料",
  "是否解析指定文档、表格或附件",
  "某项数据、结论或引用是否准确可用",
  "是否继续执行下一步自动化任务",
];

function useModalState() {
  const [authMode, setAuthMode] = React.useState(null);
  const [checkoutPlan, setCheckoutPlan] = React.useState(null);
  const [paidPlan, setPaidPlan] = React.useState(null);
  return {
    authMode,
    checkoutPlan,
    paidPlan,
    openLogin: () => setAuthMode("login"),
    openRegister: () => setAuthMode("register"),
    closeAuth: () => setAuthMode(null),
    openCheckout: (plan) => setCheckoutPlan(plan),
    closeCheckout: () => setCheckoutPlan(null),
    completePayment: (plan, order) => {
      setCheckoutPlan(null);
      setPaidPlan({ ...plan, order });
    },
    closePaid: () => setPaidPlan(null),
  };
}

function SiteNav({ actions }) {
  const [open, setOpen] = React.useState(false);
  const links = [
    ["#product", "产品"],
    ["#workflow", "流程"],
    ["manual.html", "手册"],
    ["download.html", "下载"],
    ["#faq", "FAQ"],
  ];

  return (
    <header className="site-nav">
      <a className="site-brand" href="#top" aria-label="ChenShu 首页">
        <span className="site-brand-mark"></span>
        <span>
          <strong>{PRODUCT.name}</strong>
          <small>环评行业 AI 工作台</small>
        </span>
      </a>
      <button
        className="menu-button"
        type="button"
        aria-label="打开导航"
        aria-expanded={open}
        onClick={() => setOpen((v) => !v)}
      >
        <span></span>
        <span></span>
        <span></span>
      </button>
      <nav className={open ? "site-links open" : "site-links"} aria-label="主导航">
        {links.map(([href, label]) => (
          <a key={href} href={href} onClick={() => setOpen(false)}>{label}</a>
        ))}
      </nav>
      <div className="site-actions">
        <button type="button" className="text-button" onClick={actions.openLogin}>登录</button>
        <button type="button" className="solid-button small" onClick={actions.openRegister}>注册</button>
      </div>
    </header>
  );
}

function ProductPreview({ actions }) {
  return (
    <div className="product-frame" aria-label="ChenShu 环评工作台界面预览">
      <div className="frame-titlebar">
        <span className="frame-brand-dot"></span>
        <b>ChenShu</b>
        <small>workspace / 环评项目资料</small>
        <i></i>
      </div>
      <div className="frame-body">
        <aside className="frame-sidebar">
          <button className="frame-new" type="button">新建项目会话</button>
          {["资料解析", "工程分析", "现状调查", "专家意见"].map((item, index) => (
            <div className={index === 0 ? "frame-session active" : "frame-session"} key={item}>
              <span></span>
              <p>{item}</p>
            </div>
          ))}
        </aside>
        <main className="frame-main">
          <div className="frame-message user">
            <span>用户</span>
            <p>请在本地解析这个环评项目资料包，先找出缺失材料和需要核实的数据。</p>
          </div>
          <div className="frame-message assistant">
            <span>CHENSHU AGENT</span>
            <p>已完成本地资料索引。发现 3 项数据口径需核实，是否继续生成核查清单？</p>
          </div>
          <div className="frame-tools">
            <div>
              <small>资料</small>
              <strong>本地</strong>
            </div>
            <div>
              <small>流程</small>
              <strong>环评</strong>
            </div>
            <div>
              <small>确认</small>
              <strong>用户</strong>
            </div>
          </div>
          <pre className="frame-code">{`decision.required = true
action = "生成核查清单"
owner = "用户确认后执行"`}</pre>
        </main>
        <aside className="frame-context">
          <small>当前套餐</small>
          <strong>¥599</strong>
          <p>终身授权</p>
          <button type="button" onClick={() => actions.openCheckout(PLANS[1])}>选择</button>
        </aside>
      </div>
    </div>
  );
}

function Hero({ actions }) {
  const heroCapabilities = [
    ["01", "本地化部署", "项目资料留在本机，解析、检索、生成不上传第三方平台。", "#feature-local"],
    ["02", "项目知识库", "自动入库、比对冲突、持续更新，形成项目事实底座。", "#feature-knowledge"],
    ["03", "报告生成", "基于项目资料生成报告、PPT、PDF 和整改回复草稿。", "#feature-advisor"],
    ["04", "会议应答", "实时纪要、识别专家问题，快速定位依据和回答建议。", "#feature-meeting"],
  ];
  const handleFeatureJump = (event, href) => {
    if (!href.startsWith("#")) {
      return;
    }

    const target = document.querySelector(href);
    if (!target) {
      return;
    }

    event.preventDefault();

    const reduceMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    const rect = target.getBoundingClientRect();
    const centeredTop = window.scrollY + rect.top - ((window.innerHeight - rect.height) / 2);
    window.scrollTo({
      top: Math.max(0, centeredTop),
      behavior: reduceMotion ? "auto" : "smooth",
    });
    target.focus({ preventScroll: true });
    window.history.pushState(null, "", href);
  };

  return (
    <section
      className="site-hero"
      id="top"
    >
      <div className="hero-copy">
        <h1 className="hero-main-title">面向环评工程师的 AI 工作台</h1>
        <p className="hero-lede">
          ChenShu 把资料整理、知识库构建、数据比对、报告生成、会议实时纪要和现场答疑交给本机 Agent，让你把精力留给判断、思考和决策上。
          <span className="hero-security-underline">项目的所有资料、数据全部留在你的设备上，安全不外泄！</span>
        </p>
        <div className="hero-buttons">
          <a className="solid-button" href={PRODUCT.downloadUrl}>下载程序</a>
          <button type="button" className="outline-button" onClick={actions.openRegister}>注册试用</button>
          <a className="outline-button" href="manual.html">查看手册</a>
        </div>
      </div>
      <aside className="hero-showcase" aria-label="ChenShu 产品界面与核心能力">
        <img
          className="hero-product-screenshot"
          src="assets/chenshu-workbench-hero-hd-mosaic.png"
          width="2188"
          height="1938"
          loading="eager"
          decoding="async"
          fetchPriority="high"
          alt="ChenShu 桌面工作台界面截图"
        />
      </aside>
      <div className="hero-capability-panel" aria-label="ChenShu 核心能力">
        {heroCapabilities.map(([num, title, body, href]) => (
          <a
            className="hero-capability-card"
            href={href}
            key={title}
            onClick={(event) => handleFeatureJump(event, href)}
          >
            <span>{num}</span>
            <h2>{title}</h2>
            <p>{body}</p>
          </a>
        ))}
      </div>
    </section>
  );
}

function LogoStrip() {
  return (
    <section className="logo-strip" aria-label="核心能力">
      {["本地化部署", "项目知识库", "报告生成", "会议应答", "专业绘图", "用户确认"].map((item) => (
        <span key={item}>{item}</span>
      ))}
    </section>
  );
}

function MeetingAssistantVisual() {
  const expertQuestions = [
    ["专家 A", "监测点位为何设在这里？"],
    ["专家 B", "PM2.5 数据与报告第4章矛盾"],
    ["专家 C", "该措施有无行业标准依据？"],
  ];
  const assistantActions = [
    "实时捕捉专家发言\n自动识别问题类型",
    "定位项目报告页码\n调取相关法规条文",
    "网络检索行业案例\n生成回答建议文本",
  ];
  const painPoints = ["被专家问住", "资料翻不到", "节奏被打乱"];

  return (
    <div className="feature-visual meeting meeting-diagram" aria-label="会议助手现场应答示意图">
      <div className="meeting-scene-card">
        <div className="meeting-scene-title">环评评审会现场</div>
        <div className="meeting-question-list">
          {expertQuestions.map(([expert, question]) => (
            <div className="meeting-question-row" key={expert}>
              <span>{expert}</span>
              <p>「{question}」</p>
            </div>
          ))}
        </div>
        <div className="meeting-engineer">
          <b>工程师</b>
          <small>稳稳接住</small>
        </div>
      </div>

      <div className="meeting-assistant-card">
        <h4>ChenShu 会议助手</h4>
        {assistantActions.map((item, index) => (
          <div className={`meeting-action action-${index + 1}`} key={item}>
            {item.split("\n").map((line) => (
              <span key={line}>{line}</span>
            ))}
          </div>
        ))}
      </div>

      <div className="meeting-link horizontal"></div>
      <div className="meeting-link diagonal"></div>

      <div className="meeting-result-card">
        <span>过去的痛点</span>
        <div className="meeting-pain-list">
          {painPoints.map((item) => (
            <strong key={item}>{item}</strong>
          ))}
        </div>
        <p>ChenShu 在场：依据秒出，回答有底气，汇报节奏不乱</p>
      </div>
    </div>
  );
}

function KnowledgeBaseVisual() {
  const inputSources = ["可研报告 / Word", "监测数据 / Excel", "图纸 / CAD", "会议纪要", "专家意见", "甲方补充材料"];
  const baseFacts = ["事实已校验", "数据可追溯", "版本已同步"];
  const outputs = ["报告章节", "汇报 PPT", "整改说明"];
  const alerts = [
    "污染物浓度 第3章 vs 附件4 不一致",
    "建设规模 专家意见版本早于补充材料",
  ];

  return (
    <div className="feature-visual knowledge knowledge-flow" aria-label="项目知识库从资料入库到生成输出的工作流示意图">
      <div className="knowledge-sources">
        <span>原始资料（散乱）</span>
        <div className="knowledge-source-list">
          {inputSources.map((source) => (
            <div className="knowledge-source-item" key={source}>{source}</div>
          ))}
        </div>
      </div>

      <div className="knowledge-node knowledge-engine">
        <strong>ChenShu</strong>
        <span>自动解析 · 入库</span>
        <span>跨资料比对</span>
        <span>版本追踪 · 更新</span>
      </div>

      <div className="knowledge-node knowledge-base">
        <strong>项目知识底座</strong>
        {baseFacts.map((fact) => (
          <span key={fact}>{fact}</span>
        ))}
      </div>

      <div className="knowledge-output">
        <span>生成输出</span>
        <div>
          {outputs.map((output) => (
            <strong key={output}>{output}</strong>
          ))}
        </div>
      </div>

      <div className="knowledge-alert">
        <strong>自动标记问题示意</strong>
        {alerts.map((alert) => (
          <p key={alert}>「{alert}」</p>
        ))}
      </div>

      <div className="knowledge-line source-to-engine" aria-hidden="true"></div>
      <div className="knowledge-line engine-to-base" aria-hidden="true"></div>
      <div className="knowledge-line base-to-output" aria-hidden="true"></div>
      <div className="knowledge-line alert-to-engine" aria-hidden="true"></div>
    </div>
  );
}

function AdvisorIndustryVisual() {
  return (
    <div className="feature-visual advisor advisor-industry-map" aria-label="ChenShu 环评行业知识大脑能力示意图">
      <svg className="advisor-map-lines" viewBox="0 0 100 100" aria-hidden="true" focusable="false">
        <line x1="50" y1="39" x2="22" y2="58" />
        <line x1="50" y1="39" x2="50" y2="58" />
        <line x1="50" y1="39" x2="78" y2="58" />
        <line x1="22" y1="76" x2="42" y2="87" />
        <line x1="50" y1="76" x2="50" y2="87" />
        <line x1="78" y1="76" x2="58" y2="87" />
      </svg>
      <div className="advisor-map-top advisor-map-generic">通用 AI（无行业能力）</div>
      <div className="advisor-map-not">≠</div>
      <div className="advisor-map-top advisor-map-chenshu">ChenShu：内置行业知识大脑的环评专业工作台</div>
      <div className="advisor-map-more" aria-hidden="true">•••</div>

      <div className="advisor-map-brain">
        <strong>行业知识大脑</strong>
        <span>环评工程师专业技能 · 内置行业数据库</span>
        <span>法规体系 · 技术规范 · 案例积累</span>
      </div>

      <div className="advisor-map-capability advisor-map-drawing">
        <strong>图纸解析</strong>
        <span>读懂 CAD 与工程附图</span>
        <span>提取项目参数与坐标</span>
        <span>核查平面布局合理性</span>
      </div>
      <div className="advisor-map-capability advisor-map-search">
        <strong>行业深度检索</strong>
        <span>法规依据精准定位</span>
        <span>标准条文与技术规范</span>
        <span>行业案例与判断参考</span>
      </div>
      <div className="advisor-map-capability advisor-map-output">
        <strong>专业文件生成</strong>
        <span>Word 报告 · 汇报 PPT</span>
        <span>整改说明 · PDF 材料包</span>
        <span>可提交 · 可修改 · 可报批</span>
      </div>

      <div className="advisor-map-bottom advisor-map-owner">最终确认权在工程师</div>
      <div className="advisor-map-bottom advisor-map-result">
        <strong>工程师拿到的结果</strong>
        <span>有依据的判断 · 可提交的文件 · 更快的交付</span>
      </div>
      <div className="advisor-map-bottom advisor-map-role">AI负责查找与起草</div>
    </div>
  );
}

function FeatureVisual({ feature }) {
  if (feature.id === "meeting") {
    return <MeetingAssistantVisual />;
  }
  if (feature.id === "knowledge") {
    return <KnowledgeBaseVisual />;
  }
  if (feature.id === "advisor") {
    return <AdvisorIndustryVisual />;
  }

  const visuals = {
    local: {
      title: "本地项目工作区",
      status: "未连接第三方资料云",
      rows: [
        ["可研报告.pdf", "本机解析完成", "P42"],
        ["监测数据.xlsx", "已建立索引", "本地"],
        ["专家意见.docx", "待用户确认", "安全"],
      ],
      command: "资料解析、检索和生成均在本机执行",
      output: "项目文件未上传第三方 AI 平台",
    },
    knowledge: {
      title: "项目知识库",
      status: "发现 4 项待确认冲突",
      rows: [
        ["建设规模", "报告正文 vs 可研", "需确认"],
        ["监测点位", "附件表格缺少坐标", "待补齐"],
        ["专家意见", "新增整改要求", "已入库"],
      ],
      command: "跨文档比对项目事实、版本和缺失项",
      output: "形成可追问、可比对、可生成的事实底座",
    },
    advisor: {
      title: "工程师顾问",
      status: "正在生成交付材料",
      rows: [
        ["项目问答", "数据来源与章节依据", "秒级"],
        ["法规口径", "关联行业数据库", "建议"],
        ["成果输出", "Word / PPT / PDF", "待确认"],
      ],
      command: "先查询项目事实，再生成专业材料",
      output: "报告章节、汇报 PPT 和整改回复可继续编辑",
    },
    meeting: {
      title: "评审会现场",
      status: "专家问题已捕捉",
      rows: [
        ["专家 A", "该监测数据来源在哪里？", "问题"],
        ["ChenShu", "可研报告 P37，表 3-2", "依据"],
        ["建议回答", "先说明来源，再提示复核点", "草稿"],
      ],
      command: "实时转写多人发言，定位报告页码和原文依据",
      output: "一个人参会，也能快速应对连续追问",
    },
    drawing: {
      title: "专业绘图助手",
      status: "Roadmap / 即将推出",
      rows: [
        ["CAD", "项目边界与平面布置", "初稿"],
        ["ArcGIS", "评价范围与敏感目标图例", "制作"],
        ["3D 图样", "项目空间关系展示", "生成"],
      ],
      command: "根据项目资料和工程师指令生成图样",
      output: "复杂软件能力逐步变成本机可调用工作流",
    },
  };
  const visual = visuals[feature.id];
  return (
    <div className={`feature-visual ${feature.id}`} aria-label={`${feature.tag}界面示意`}>
      <div className="feature-visual-bar">
        <span></span>
        <b>{visual.title}</b>
        <small>{visual.status}</small>
      </div>
      <div className="feature-visual-body">
        <div className="feature-visual-table">
          {visual.rows.map(([name, detail, state]) => (
            <div className="feature-visual-row" key={`${name}-${detail}`}>
              <strong>{name}</strong>
              <span>{detail}</span>
              <em>{state}</em>
            </div>
          ))}
        </div>
        <div className="feature-command">
          <span>CHENSHU AGENT</span>
          <p>{visual.command}</p>
        </div>
        <div className="feature-output">
          <small>输出结果</small>
          <strong>{visual.output}</strong>
        </div>
      </div>
    </div>
  );
}

function splitFeatureCapability(capability) {
  const match = capability.match(/^(.+?)(?:：|\s+—\s+)(.+)$/);
  return match ? [match[1], match[2]] : [capability, ""];
}

function MeetingFeatureCopy({ feature }) {
  return (
    <div className="feature-copy-block meeting-copy">
      <div className="meeting-copy-kicker">MEETING ASSISTANT</div>
      <h3 className="meeting-copy-title">
        <span>智能生成会议纪要，</span>
        <span>并为用户提供现场问题的</span>
        <span>秒级回复建议</span>
      </h3>
      {feature.body.map((paragraph) => (
        <p className="meeting-copy-lede" key={paragraph}>{paragraph}</p>
      ))}
      <ul className="meeting-proof-list">
        {feature.capabilities.map((capability) => {
          const [capabilityName, capabilityDetail] = capability.split(" — ");
          return (
            <li key={capability}>
              <strong>{capabilityName}</strong>
              <span>{capabilityDetail}</span>
            </li>
          );
        })}
      </ul>
    </div>
  );
}

function FeatureShowcaseSkin() {
  return (
    <style>{`
      .site-section.intro-section {
        width: min(calc(100% - 48px), clamp(1180px, 85vw, 1516px));
      }

      .feature-showcase-list {
        gap: clamp(92px, 10vw, 154px) !important;
      }

      .feature-showcase {
        min-height: auto;
        overflow: visible;
        border: 0;
        border-radius: 0;
        background: transparent;
        box-shadow: none;
        grid-template-columns: minmax(320px, 0.82fr) minmax(520px, 1.18fr);
        align-items: center;
        gap: clamp(58px, 7vw, 104px);
        scroll-margin-block: 22vh;
      }

      .feature-showcase.reverse .feature-copy-block {
        border-left: 0;
      }

      .feature-showcase::before {
        content: "";
        grid-column: 1 / -1;
        height: 1px;
        width: min(100%, 980px);
        margin: 0 auto clamp(72px, 7vw, 108px);
        background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--border-strong) 72%, transparent), transparent);
      }

      .feature-showcase:first-child::before {
        display: none;
      }

      .feature-copy-block {
        max-width: 580px;
        padding: 0;
        border-right: 0;
        background: transparent;
      }

      .feature-copy-block h3 {
        max-width: 620px;
        margin-bottom: 22px;
        font-size: 42px;
        line-height: 1.04;
      }

      .feature-copy-block p {
        max-width: 560px;
        font-size: 16px;
        line-height: 1.82;
      }

      .feature-copy-block p + p {
        margin-top: 16px;
      }

      .feature-capability-list {
        margin-top: 30px;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 14px 20px;
      }

      .feature-capability-list li {
        min-height: auto;
        padding: 0 0 0 22px;
        border: 0;
        border-radius: 0;
        background: transparent;
        color: var(--fg);
        font-size: 14px;
        line-height: 1.5;
        font-weight: 760;
      }

      .feature-capability-list li::before {
        left: 2px;
        width: 7px;
        height: 7px;
      }

      .feature-emphasis {
        margin-top: 32px;
        padding: 0 0 0 18px;
        border-left: 3px solid var(--accent);
        color: var(--accent-strong);
        font-size: 18px;
        line-height: 1.48;
      }

      .feature-visual {
        min-height: 440px;
        padding: clamp(28px, 4vw, 54px);
        border: 1px solid var(--border-strong);
        border-radius: 14px;
        box-shadow: 0 32px 92px -58px rgba(23, 49, 58, 0.55);
      }

      .feature-visual-bar,
      .feature-visual-body {
        width: min(100%, 600px);
      }

      .feature-story-local .feature-visual {
        min-height: 430px;
      }

      .feature-story-knowledge .feature-visual {
        min-height: 640px;
      }

      .feature-story-knowledge {
        grid-template-columns: minmax(620px, 1.12fr) minmax(430px, 0.88fr);
        gap: clamp(44px, 5vw, 72px);
        align-items: stretch;
      }

      .feature-story-knowledge .feature-copy-block {
        max-width: 560px;
        height: 100%;
      }

      .feature-story-knowledge .feature-capability-list {
        counter-reset: knowledge-proof;
        grid-template-columns: 1fr;
        gap: 18px;
      }

      .feature-story-knowledge .feature-capability-list li {
        min-height: auto;
        padding: 0 0 0 50px;
        display: block;
      }

      .feature-story-knowledge .feature-capability-list li::before {
        counter-increment: knowledge-proof;
        content: "0" counter(knowledge-proof);
        left: 0;
        top: 4px;
        width: 28px;
        height: 28px;
        display: grid;
        place-items: center;
        border: 1px solid color-mix(in srgb, var(--agent) 38%, var(--border));
        border-radius: 8px;
        background:
          linear-gradient(135deg, color-mix(in srgb, var(--mint-soft) 80%, var(--panel)), color-mix(in srgb, var(--accent-soft) 72%, var(--panel)));
        box-shadow: none;
        color: var(--accent-strong);
        font-family: var(--mono);
        font-size: 10px;
        font-weight: 900;
        line-height: 1;
        transform: none;
      }

      .feature-story-knowledge .feature-capability-list li::after {
        content: "";
        position: absolute;
        left: 13px;
        top: 42px;
        bottom: -12px;
        border-left: 1px dashed color-mix(in srgb, var(--border-strong) 72%, transparent);
      }

      .feature-story-knowledge .feature-capability-list li:last-child::after {
        display: none;
      }

      .feature-story-knowledge .feature-capability-list strong {
        display: block;
        margin-bottom: 4px;
        color: var(--fg);
        font-size: 15px;
        font-weight: 880;
        line-height: 1.25;
      }

      .feature-story-knowledge .feature-capability-list span {
        display: block;
        color: var(--fg-2);
        font-size: 13.5px;
        font-weight: 620;
        line-height: 1.58;
      }

      .knowledge-flow {
        position: relative;
        min-height: 640px;
        height: 100%;
        padding: 34px 32px 30px;
        display: grid;
        grid-template-columns: minmax(142px, 0.82fr) minmax(164px, 0.94fr) minmax(168px, 0.96fr);
        grid-template-rows: auto minmax(156px, auto) auto minmax(82px, auto);
        gap: 18px 32px;
        align-items: center;
        align-content: center;
        overflow: hidden;
        background:
          linear-gradient(rgba(23, 49, 58, 0.028) 1px, transparent 1px),
          linear-gradient(90deg, rgba(23, 49, 58, 0.028) 1px, transparent 1px),
          color-mix(in srgb, #fbfffc 76%, var(--panel));
        background-size: 26px 26px;
      }

      .knowledge-sources {
        grid-column: 1;
        grid-row: 1 / 4;
        position: relative;
        z-index: 3;
        align-self: start;
      }

      .knowledge-sources > span,
      .knowledge-output > span,
      .knowledge-alert strong {
        display: block;
        color: var(--muted);
        font-size: 12px;
        font-weight: 720;
        line-height: 1.2;
        text-align: center;
      }

      .knowledge-source-list {
        margin-top: 12px;
        display: grid;
        gap: 10px;
      }

      .knowledge-source-item {
        min-height: 36px;
        padding: 8px 12px;
        display: grid;
        place-items: center;
        border: 1px solid color-mix(in srgb, var(--fg) 20%, var(--border));
        border-radius: 7px;
        background: color-mix(in srgb, #fbfaf4 88%, var(--panel));
        color: color-mix(in srgb, var(--fg-2) 92%, var(--fg));
        box-shadow: 0 10px 24px -22px rgba(23, 49, 58, 0.44);
        font-size: 12px;
        font-weight: 760;
        line-height: 1.25;
        text-align: center;
      }

      .knowledge-node {
        position: relative;
        z-index: 3;
        min-height: 132px;
        padding: 22px 18px;
        display: grid;
        place-items: center;
        align-content: center;
        border-radius: 13px;
        text-align: center;
      }

      .knowledge-node strong {
        margin-bottom: 7px;
        color: var(--accent-strong);
        font-size: 15px;
        font-weight: 900;
        line-height: 1.2;
      }

      .knowledge-node span {
        display: block;
        color: var(--accent-strong);
        font-size: 12px;
        font-weight: 760;
        line-height: 1.55;
      }

      .knowledge-engine {
        grid-column: 2;
        grid-row: 2;
        border: 1px solid color-mix(in srgb, var(--agent) 58%, var(--border));
        background: color-mix(in srgb, var(--mint-soft) 88%, var(--panel));
        box-shadow: 0 18px 42px -32px rgba(6, 152, 186, 0.52);
      }

      .knowledge-base {
        grid-column: 3;
        grid-row: 2;
        border: 1px solid color-mix(in srgb, #6f63d8 60%, var(--border));
        background: color-mix(in srgb, #f0edff 76%, var(--panel));
      }

      .knowledge-base strong,
      .knowledge-base span {
        color: #5b4fc0;
      }

      .knowledge-output {
        grid-column: 2 / 4;
        grid-row: 3;
        position: relative;
        z-index: 3;
        align-self: start;
        justify-self: end;
        display: grid;
        gap: 11px;
      }

      .knowledge-output div {
        display: flex;
        justify-content: center;
        flex-wrap: wrap;
        gap: 6px;
      }

      .knowledge-output strong {
        min-height: 34px;
        padding: 8px 10px;
        display: inline-grid;
        place-items: center;
        border: 1px solid color-mix(in srgb, #d86d55 48%, var(--border));
        border-radius: 7px;
        background: #fff3ee;
        color: #a14d35;
        font-size: 12px;
        font-weight: 840;
        line-height: 1.2;
        white-space: nowrap;
      }

      .knowledge-alert {
        grid-column: 1 / 3;
        grid-row: 4;
        position: relative;
        z-index: 3;
        justify-self: end;
        width: min(100%, 332px);
        padding: 14px 18px;
        border: 1px dashed color-mix(in srgb, var(--border-strong) 72%, transparent);
        border-radius: 12px;
        background: color-mix(in srgb, var(--panel) 82%, transparent);
        box-shadow: 0 18px 48px -40px rgba(23, 49, 58, 0.42);
      }

      .knowledge-alert strong {
        margin-bottom: 8px;
        text-align: left;
      }

      .knowledge-alert strong::before {
        content: "";
        width: 11px;
        height: 11px;
        margin-right: 6px;
        display: inline-block;
        border: 1px solid color-mix(in srgb, var(--fg) 44%, transparent);
        border-radius: 50%;
        vertical-align: -1px;
      }

      .knowledge-alert p {
        margin: 4px 0 0;
        color: var(--fg-2);
        font-size: 12px;
        font-weight: 700;
        line-height: 1.45;
      }

      .knowledge-line {
        position: absolute;
        z-index: 1;
        pointer-events: none;
        border-color: color-mix(in srgb, var(--border-strong) 62%, transparent);
      }

      .knowledge-line::after {
        content: "";
        position: absolute;
        width: 6px;
        height: 6px;
        border-top: 1px solid currentColor;
        border-right: 1px solid currentColor;
        color: color-mix(in srgb, var(--border-strong) 90%, var(--fg-2));
      }

      .source-to-engine {
        left: 27%;
        top: 48%;
        width: 17%;
        border-top: 1px dashed color-mix(in srgb, var(--border-strong) 72%, transparent);
      }

      .source-to-engine::after,
      .engine-to-base::after {
        right: -1px;
        top: -4px;
        transform: rotate(45deg);
      }

      .engine-to-base {
        left: 58%;
        top: 48%;
        width: 10%;
        border-top: 1px solid color-mix(in srgb, var(--border-strong) 70%, transparent);
      }

      .base-to-output {
        right: 19%;
        top: 56%;
        height: 52px;
        border-left: 1px dashed color-mix(in srgb, var(--border-strong) 62%, transparent);
      }

      .base-to-output::after {
        left: -4px;
        bottom: 0;
        transform: rotate(135deg);
      }

      .alert-to-engine {
        left: 43%;
        bottom: 18%;
        width: 90px;
        border-top: 1px dashed color-mix(in srgb, var(--border-strong) 56%, transparent);
        transform: rotate(-16deg);
        transform-origin: left center;
      }

      .alert-to-engine::after {
        left: -1px;
        top: -4px;
        transform: rotate(-135deg);
      }

      .feature-story-advisor .feature-visual {
        min-height: 470px;
      }

      .feature-story-meeting .feature-visual {
        min-height: 540px;
      }

      .feature-story-meeting {
        grid-template-columns: minmax(590px, 1fr) minmax(500px, 0.92fr);
        align-items: start;
        gap: clamp(52px, 5vw, 72px);
        scroll-margin-block: 12vh;
      }

      .feature-story-meeting::before {
        display: none;
      }

      .feature-story-meeting .feature-copy-block {
        max-width: 500px;
      }

      .feature-story-meeting .feature-copy-block::before {
        content: "会议助手 / 现场答疑";
        width: max-content;
        margin-bottom: 20px;
        padding: 7px 11px;
        display: inline-flex;
        border: 1px solid color-mix(in srgb, var(--accent) 30%, var(--border));
        border-radius: 999px;
        background: color-mix(in srgb, var(--accent-soft) 52%, transparent);
        color: var(--accent-strong);
        font-family: var(--mono);
        font-size: 12px;
        font-weight: 820;
        letter-spacing: 0.02em;
      }

      .feature-story-meeting .meeting-copy::before {
        content: none;
        display: none;
      }

      .meeting-copy {
        max-width: 540px;
        padding-block: 0;
      }

      .meeting-copy-kicker {
        margin-bottom: 18px;
        display: inline-flex;
        align-items: center;
        gap: 10px;
        color: var(--accent-strong);
        font-family: var(--mono);
        font-size: 12px;
        font-weight: 860;
        letter-spacing: 0.04em;
      }

      .meeting-copy-kicker::before {
        content: "";
        width: 34px;
        height: 1px;
        background: var(--accent);
      }

      .meeting-copy-title {
        max-width: 540px;
        margin: 0;
        color: var(--fg);
        font-size: 42px;
        line-height: 1.08;
      }

      .meeting-copy-title span {
        display: block;
      }

      .meeting-copy-lede {
        margin: 24px 0 0;
        max-width: 520px;
        color: color-mix(in srgb, var(--fg-2) 88%, var(--fg));
        font-size: 16.5px;
        line-height: 1.9;
      }

      .meeting-proof-list {
        margin: 30px 0 0;
        padding: 24px 0 0;
        display: grid;
        gap: 20px;
        border-top: 1px solid color-mix(in srgb, var(--border-strong) 58%, transparent);
        list-style: none;
      }

      .meeting-proof-list li {
        position: relative;
        padding-left: 22px;
        color: var(--fg);
      }

      .meeting-proof-list li::before {
        content: "";
        position: absolute;
        left: 0;
        top: 8px;
        width: 7px;
        height: 7px;
        border-radius: 50%;
        background: var(--agent);
        box-shadow: 0 0 0 5px var(--agent-soft);
      }

      .meeting-proof-list strong {
        display: block;
        margin-bottom: 5px;
        color: var(--fg);
        font-size: 16px;
        font-weight: 880;
        line-height: 1.25;
      }

      .meeting-proof-list span {
        display: block;
        max-width: 430px;
        color: var(--fg-2);
        font-size: 14px;
        font-weight: 620;
        line-height: 1.65;
      }

      .feature-story-meeting .feature-copy-block h3 {
        max-width: 480px;
        margin-bottom: 24px;
        line-height: 1.08;
        text-wrap: balance;
      }

      .feature-story-meeting .feature-copy-block p {
        max-width: 500px;
        color: color-mix(in srgb, var(--fg-2) 88%, var(--fg));
        font-size: 16.5px;
        line-height: 1.9;
      }

      .feature-story-meeting .feature-capability-list {
        margin-top: 34px;
        counter-reset: meeting-proof;
        grid-template-columns: 1fr;
        gap: 18px;
        border-top: 0;
      }

      .feature-story-meeting .feature-capability-list li {
        min-height: auto;
        padding: 0 0 0 50px;
        position: relative;
        display: block;
        border-bottom: 0;
        color: var(--fg);
        font-size: 14px;
        font-weight: 700;
        line-height: 1.52;
      }

      .feature-story-meeting .feature-capability-list li:nth-child(odd) {
        padding-right: 0;
      }

      .feature-story-meeting .feature-capability-list li:nth-child(even) {
        padding-left: 50px;
      }

      .feature-story-meeting .feature-capability-list li::before {
        counter-increment: meeting-proof;
        content: "0" counter(meeting-proof);
        position: absolute;
        left: 0;
        top: 2px;
        width: 30px;
        height: 30px;
        display: grid;
        place-items: center;
        border: 1px solid color-mix(in srgb, var(--accent) 28%, var(--border));
        border-radius: 999px;
        background: color-mix(in srgb, var(--accent-soft) 44%, transparent);
        box-shadow: none;
        color: var(--accent);
        font-family: var(--mono);
        font-size: 11px;
        font-weight: 900;
        line-height: 1;
        transform: none;
      }

      .feature-story-meeting .feature-capability-list li:not(:last-child)::after {
        content: "";
        position: absolute;
        left: 15px;
        top: 38px;
        bottom: -12px;
        border-left: 1px solid color-mix(in srgb, var(--border-strong) 56%, transparent);
      }

      .feature-story-meeting .feature-capability-list li strong {
        display: block;
        margin-bottom: 5px;
        color: var(--fg);
        font-size: 15.5px;
        font-weight: 880;
        line-height: 1.25;
      }

      .feature-story-meeting .feature-capability-list li span {
        display: block;
        color: var(--fg-2);
        font-size: 13.5px;
        font-weight: 650;
        line-height: 1.58;
      }

      .meeting-diagram {
        position: relative;
        min-height: 560px;
        display: grid;
        grid-template-columns: minmax(300px, 1.45fr) minmax(170px, 0.75fr);
        grid-template-rows: minmax(280px, auto) auto;
        align-items: start;
        gap: 22px 24px;
        padding: 28px;
        background: color-mix(in srgb, #f8fffb 58%, var(--panel));
      }

      .meeting-scene-card,
      .meeting-assistant-card,
      .meeting-result-card {
        position: relative;
        z-index: 2;
        border: 1px solid var(--border-strong);
        background: color-mix(in srgb, var(--card) 88%, transparent);
      }

      .meeting-scene-card {
        min-height: 280px;
        padding: 22px 24px;
        border-radius: 14px;
      }

      .meeting-scene-title {
        margin-bottom: 18px;
        color: var(--muted);
        font-size: 13px;
        text-align: center;
      }

      .meeting-question-list {
        display: grid;
        gap: 12px;
      }

      .meeting-question-row {
        display: grid;
        grid-template-columns: 92px minmax(0, 1fr);
        align-items: center;
        gap: 10px;
      }

      .meeting-question-row span {
        min-height: 38px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        border: 1px solid color-mix(in srgb, #d86d55 42%, var(--border));
        border-radius: 9px;
        background: color-mix(in srgb, #fff0ea 72%, var(--panel));
        color: #9b3f2f;
        font-size: 13px;
        font-weight: 820;
      }

      .meeting-question-row p {
        min-height: 38px;
        margin: 0;
        padding: 9px 12px;
        display: flex;
        align-items: center;
        border: 1px solid var(--border);
        border-radius: 8px;
        background: var(--panel);
        color: var(--fg-2);
        font-size: 13px;
        line-height: 1.35;
      }

      .meeting-engineer {
        position: absolute;
        right: 24px;
        bottom: 20px;
        display: grid;
        justify-items: center;
        gap: 4px;
      }

      .meeting-engineer b {
        width: 52px;
        height: 52px;
        display: grid;
        place-items: center;
        border: 1px solid var(--border-strong);
        border-radius: 50%;
        background: color-mix(in srgb, #efe8ff 62%, var(--panel));
        color: var(--fg);
        font-size: 12px;
      }

      .meeting-engineer small {
        color: #4c7b55;
        font-size: 13px;
        font-weight: 800;
      }

      .meeting-assistant-card {
        margin-top: 32px;
        padding: 22px 16px;
        border-color: color-mix(in srgb, var(--agent) 48%, var(--border));
        border-radius: 14px;
        background: color-mix(in srgb, var(--mint-soft) 74%, var(--panel));
      }

      .meeting-assistant-card h4 {
        margin: 0 0 14px;
        color: #087c70;
        font-size: 17px;
        text-align: center;
      }

      .meeting-action {
        min-height: 44px;
        margin-top: 10px;
        padding: 8px 12px;
        display: grid;
        place-items: center;
        border: 1px solid var(--border-strong);
        border-radius: 7px;
        font-size: 12px;
        font-weight: 800;
        line-height: 1.25;
        text-align: center;
      }

      .meeting-action span {
        display: block;
      }

      .meeting-action.action-1 {
        background: #f0edff;
        color: #5f4cc6;
        border-color: #afa6ff;
      }

      .meeting-action.action-2 {
        background: #eef8ff;
        color: #1875a3;
        border-color: #91cdef;
      }

      .meeting-action.action-3 {
        background: #fff4df;
        color: #996319;
        border-color: #edc47b;
      }

      .meeting-result-card {
        grid-column: 1 / -1;
        padding: 18px 28px;
        border-radius: 12px;
        text-align: center;
      }

      .meeting-result-card > span {
        display: block;
        margin-bottom: 9px;
        color: var(--muted);
        font-size: 13px;
      }

      .meeting-pain-list {
        display: grid;
        grid-template-columns: repeat(3, 1fr);
        gap: 14px;
      }

      .meeting-pain-list strong {
        color: #cf3f45;
        font-size: 13px;
      }

      .meeting-result-card p {
        margin: 12px 0 0;
        color: #2d7b3d;
        font-size: 14px;
        font-weight: 850;
      }

      .meeting-link {
        position: absolute;
        z-index: 1;
        border-top: 1px dashed color-mix(in srgb, var(--border-strong) 88%, transparent);
        pointer-events: none;
      }

      .meeting-link.horizontal {
        top: 47%;
        left: 51%;
        width: 18%;
      }

      .meeting-link.diagonal {
        right: 28%;
        bottom: 24%;
        width: 28%;
        transform: rotate(-17deg);
        transform-origin: right center;
      }

      .feature-story-drawing .feature-visual {
        min-height: 390px;
      }

      @media (max-width: 1080px) {
        .site-section.intro-section {
          width: min(calc(100% - 32px), var(--maxw));
        }

        .feature-showcase,
        .feature-showcase.reverse {
          grid-template-columns: 1fr;
          gap: 34px;
        }

        .feature-showcase.reverse .feature-copy-block,
        .feature-showcase.reverse .feature-visual {
          order: initial;
        }

        .feature-showcase .feature-copy-block,
        .feature-showcase.reverse .feature-copy-block {
          border: 0;
        }

        .feature-copy-block {
          max-width: 720px;
        }

        .feature-visual {
          min-height: 420px;
        }

        .feature-story-meeting {
          grid-template-columns: 1fr;
        }

        .feature-story-knowledge {
          grid-template-columns: 1fr;
        }

        .knowledge-flow {
          min-height: auto;
          grid-template-columns: minmax(150px, 0.86fr) minmax(160px, 0.94fr) minmax(170px, 1fr);
          gap: 16px 24px;
        }

        .meeting-diagram {
          grid-template-columns: 1fr;
        }

        .meeting-assistant-card {
          margin-top: 0;
        }

        .meeting-link {
          display: none;
        }
      }

      @media (max-width: 680px) {
        .site-section.intro-section {
          width: min(calc(100% - 28px), var(--maxw));
        }

        .site-hero {
          width: min(calc(100% - 28px), var(--maxw)) !important;
          min-height: auto !important;
          grid-template-columns: 1fr !important;
          gap: 32px !important;
        }

        .hero-main-title {
          white-space: normal !important;
        }

        .hero-capability-panel {
          max-width: 100% !important;
          grid-template-columns: 1fr !important;
        }

        .feature-showcase-list {
          gap: 72px !important;
        }

        .feature-showcase::before {
          margin-bottom: 58px;
        }

        .feature-capability-list {
          grid-template-columns: 1fr;
        }

        .feature-story-meeting .feature-capability-list {
          grid-template-columns: 1fr;
        }

        .feature-story-meeting .feature-capability-list li,
        .feature-story-meeting .feature-capability-list li:nth-child(odd),
        .feature-story-meeting .feature-capability-list li:nth-child(even) {
          min-height: auto;
          padding: 0 0 0 50px;
        }

        .feature-visual {
          padding: 18px;
          min-height: auto;
        }

        .knowledge-flow {
          grid-template-columns: 1fr;
          grid-template-rows: auto;
          gap: 16px;
          padding: 22px 18px;
          overflow: visible;
        }

        .knowledge-sources,
        .knowledge-engine,
        .knowledge-base,
        .knowledge-output,
        .knowledge-alert {
          grid-column: 1;
          grid-row: auto;
          width: 100%;
          justify-self: stretch;
        }

        .knowledge-sources {
          align-self: stretch;
        }

        .knowledge-sources > span,
        .knowledge-output > span {
          text-align: left;
        }

        .knowledge-source-list {
          gap: 8px;
        }

        .knowledge-node {
          min-height: 116px;
        }

        .knowledge-output div {
          justify-content: flex-start;
          flex-wrap: wrap;
        }

        .knowledge-alert {
          padding: 14px;
        }

        .knowledge-line {
          display: none;
        }

        .meeting-question-row,
        .meeting-pain-list {
          grid-template-columns: 1fr;
        }

        .meeting-engineer {
          position: static;
          margin-top: 20px;
        }
      }

      .feature-showcase-list {
        gap: clamp(26px, 4vw, 44px) !important;
      }

      .feature-showcase.feature-panel,
      .feature-showcase.feature-panel.feature-story-knowledge,
      .feature-showcase.feature-panel.feature-story-meeting {
        min-height: auto;
        padding: clamp(30px, 3.9vw, 46px) clamp(28px, 4.8vw, 54px);
        display: grid;
        grid-template-columns: minmax(0, 0.82fr) minmax(500px, 1.08fr);
        align-items: stretch;
        gap: clamp(36px, 5vw, 68px);
        overflow: hidden;
        border: 1px solid var(--border-strong);
        border-radius: 12px;
        background: color-mix(in srgb, var(--mint-soft) 48%, var(--panel));
        box-shadow: 0 24px 70px -42px rgba(23, 49, 58, 0.34);
        scroll-margin-block: 18vh;
      }

      .feature-showcase.feature-panel::before,
      .feature-showcase.feature-panel.feature-story-meeting::before {
        content: none;
        display: none;
      }

      .feature-showcase.feature-panel .feature-copy-block,
      .feature-showcase.feature-panel.feature-story-knowledge .feature-copy-block,
      .feature-showcase.feature-panel.feature-story-meeting .feature-copy-block {
        width: 100%;
        max-width: none;
        height: 100%;
        padding: 0;
        display: flex;
        flex-direction: column;
        justify-content: center;
        border: 0;
        background: transparent;
      }

      .feature-showcase.feature-panel .feature-copy-block::before,
      .feature-showcase.feature-panel.feature-story-meeting .feature-copy-block::before {
        content: none;
        display: none;
      }

      .feature-panel-kicker {
        margin-bottom: 18px;
        color: var(--accent-strong);
        font-size: 14px;
        font-weight: 900;
        line-height: 1.2;
        letter-spacing: 0;
      }

      .feature-showcase.feature-panel .feature-copy-block h3,
      .feature-showcase.feature-panel.feature-story-meeting .feature-copy-block h3 {
        max-width: 640px;
        margin: 0 0 18px;
        color: var(--fg);
        font-size: clamp(34px, 4vw, 52px);
        font-weight: 900;
        line-height: 1.05;
        letter-spacing: 0;
        text-wrap: balance;
      }

      .feature-showcase.feature-panel .feature-copy-block p,
      .feature-showcase.feature-panel.feature-story-meeting .feature-copy-block p {
        max-width: 630px;
        margin: 0;
        color: var(--fg-2);
        font-size: 16px;
        font-weight: 520;
        line-height: 1.78;
      }

      .feature-showcase.feature-panel .feature-copy-block p + p {
        margin-top: 10px;
      }

      .feature-showcase.feature-panel .feature-capability-list,
      .feature-showcase.feature-panel.feature-story-knowledge .feature-capability-list,
      .feature-showcase.feature-panel.feature-story-meeting .feature-capability-list {
        margin-top: 24px;
        padding: 0;
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 10px;
        border: 0;
        list-style: none;
        counter-reset: none;
      }

      .feature-showcase.feature-panel .feature-capability-list li,
      .feature-showcase.feature-panel.feature-story-knowledge .feature-capability-list li,
      .feature-showcase.feature-panel.feature-story-meeting .feature-capability-list li,
      .feature-showcase.feature-panel.feature-story-meeting .feature-capability-list li:nth-child(odd),
      .feature-showcase.feature-panel.feature-story-meeting .feature-capability-list li:nth-child(even) {
        min-height: 62px;
        padding: 13px 14px 13px 42px;
        position: relative;
        display: flex;
        flex-direction: column;
        justify-content: center;
        border: 1px solid var(--border);
        border-radius: 8px;
        background: color-mix(in srgb, var(--card) 88%, transparent);
        color: var(--fg-2);
        font-size: 13.5px;
        font-weight: 700;
        line-height: 1.45;
      }

      .feature-showcase.feature-panel .feature-capability-list li::before,
      .feature-showcase.feature-panel.feature-story-knowledge .feature-capability-list li::before,
      .feature-showcase.feature-panel.feature-story-meeting .feature-capability-list li::before {
        content: "";
        position: absolute;
        left: 14px;
        top: 50%;
        width: 14px;
        height: 14px;
        transform: translateY(-50%);
        border: 0;
        border-radius: 50%;
        background:
          linear-gradient(45deg, transparent 46%, #fff 46% 56%, transparent 56%),
          linear-gradient(-45deg, transparent 43%, #fff 43% 53%, transparent 53%),
          var(--agent);
        box-shadow: none;
      }

      .feature-showcase.feature-panel .feature-capability-list li::after,
      .feature-showcase.feature-panel.feature-story-knowledge .feature-capability-list li::after,
      .feature-showcase.feature-panel.feature-story-meeting .feature-capability-list li::after,
      .feature-showcase.feature-panel.feature-story-meeting .feature-capability-list li:not(:last-child)::after {
        content: none;
        display: none;
      }

      .feature-showcase.feature-panel .feature-capability-list strong,
      .feature-showcase.feature-panel.feature-story-knowledge .feature-capability-list strong,
      .feature-showcase.feature-panel.feature-story-meeting .feature-capability-list li strong {
        display: block;
        margin: 0;
        color: var(--fg);
        font-size: 14px;
        font-weight: 820;
        line-height: 1.32;
      }

      .feature-showcase.feature-panel .feature-capability-list span,
      .feature-showcase.feature-panel.feature-story-knowledge .feature-capability-list span,
      .feature-showcase.feature-panel.feature-story-meeting .feature-capability-list li span {
        display: block;
        margin-top: 4px;
        color: var(--fg-2);
        font-size: 12.5px;
        font-weight: 560;
        line-height: 1.45;
      }

      .feature-showcase.feature-panel .feature-emphasis {
        width: fit-content;
        max-width: 100%;
        margin-top: 22px;
        padding: 10px 14px;
        border: 1px solid color-mix(in srgb, var(--accent) 26%, var(--border));
        border-radius: 8px;
        background: color-mix(in srgb, var(--panel) 76%, transparent);
        color: var(--accent-strong);
        font-size: 14px;
        font-weight: 820;
        line-height: 1.45;
      }

      .feature-showcase.feature-panel .feature-visual {
        width: 100%;
        height: 100%;
        min-height: 430px;
        align-self: stretch;
        border-radius: 10px;
        box-shadow: none;
      }

      .feature-showcase.feature-panel.feature-story-knowledge .feature-visual {
        min-height: 640px;
      }

      .feature-showcase.feature-panel.feature-story-meeting .feature-visual {
        min-height: 540px;
      }

      .feature-showcase.feature-panel.feature-story-advisor .feature-visual {
        min-height: 600px;
      }

      .feature-showcase.feature-panel .feature-visual-bar,
      .feature-showcase.feature-panel .feature-visual-body {
        width: 100%;
      }

      .advisor-industry-map {
        position: relative;
        min-height: 600px;
        padding: 28px 30px 26px;
        display: grid;
        grid-template-columns: repeat(12, minmax(0, 1fr));
        grid-template-rows: 40px 112px 64px 140px 62px;
        gap: 16px 12px;
        align-items: center;
        align-content: center;
        overflow: hidden;
        background: color-mix(in srgb, #fbfffc 82%, var(--panel));
      }

      .advisor-map-lines {
        position: absolute;
        inset: 0;
        z-index: 1;
        width: 100%;
        height: 100%;
        pointer-events: none;
      }

      .advisor-map-lines line {
        stroke: color-mix(in srgb, var(--border-strong) 64%, transparent);
        stroke-width: 1;
        vector-effect: non-scaling-stroke;
      }

      .advisor-map-top,
      .advisor-map-brain,
      .advisor-map-capability,
      .advisor-map-bottom {
        position: relative;
        z-index: 2;
        display: grid;
        place-items: center;
        align-content: center;
        text-align: center;
      }

      .advisor-map-top {
        min-height: 34px;
        min-width: 0;
        padding: 8px 12px;
        border: 1px solid var(--border-strong);
        border-radius: 8px;
        background: color-mix(in srgb, var(--card) 88%, transparent);
        color: var(--fg-2);
        font-size: 12px;
        font-weight: 760;
        line-height: 1.2;
      }

      .advisor-map-generic {
        grid-column: 1 / 5;
        border-style: dashed;
        color: var(--muted);
      }

      .advisor-map-not {
        grid-column: 5 / 6;
        justify-self: center;
        color: var(--danger);
        font-size: 14px;
        font-weight: 900;
      }

      .advisor-map-chenshu {
        grid-column: 6 / 13;
        background: color-mix(in srgb, var(--mint-soft) 86%, var(--panel));
        color: var(--accent-strong);
        font-size: 13px;
        font-weight: 900;
      }

      .advisor-map-more {
        position: absolute;
        top: 18px;
        right: 22px;
        z-index: 3;
        color: var(--fg);
        font-size: 16px;
        letter-spacing: 2px;
      }

      .advisor-map-brain {
        grid-column: 4 / 10;
        grid-row: 2;
        justify-self: center;
        width: min(100%, 274px);
        min-height: 112px;
        padding: 18px 22px;
        border: 1px solid color-mix(in srgb, var(--accent-strong) 70%, var(--border));
        border-radius: 14px;
        background: color-mix(in srgb, var(--mint-soft) 74%, var(--panel));
        color: var(--accent-strong);
      }

      .advisor-map-brain strong,
      .advisor-map-capability strong,
      .advisor-map-result strong {
        display: block;
        margin-bottom: 6px;
        color: inherit;
        font-size: 14px;
        font-weight: 900;
        line-height: 1.2;
      }

      .advisor-map-brain span,
      .advisor-map-capability span,
      .advisor-map-result span {
        display: block;
        color: inherit;
        font-size: 11.8px;
        font-weight: 690;
        line-height: 1.45;
      }

      .advisor-map-capability {
        grid-row: 4;
        min-height: 140px;
        padding: 15px 12px;
        border: 1px solid var(--border-strong);
        border-radius: 12px;
        background: var(--card);
      }

      .advisor-map-drawing {
        grid-column: 1 / 5;
        border-color: #a9a0f0;
        background: #f1efff;
        color: #5d55ba;
      }

      .advisor-map-search {
        grid-column: 5 / 9;
        border-color: #94bfe7;
        background: #eaf6ff;
        color: #1b74ad;
      }

      .advisor-map-output {
        grid-column: 9 / 13;
        border-color: #d5aa70;
        background: #fff0dc;
        color: #9b6324;
      }

      .advisor-map-bottom {
        grid-row: 5;
        min-height: 42px;
        padding: 9px 12px;
        border: 1px solid var(--border);
        border-radius: 8px;
        background: color-mix(in srgb, var(--panel) 82%, transparent);
        color: var(--fg-2);
        font-size: 12px;
        font-weight: 720;
        line-height: 1.25;
      }

      .advisor-map-owner {
        grid-column: 1 / 4;
      }

      .advisor-map-result {
        grid-column: 4 / 10;
      }

      .advisor-map-role {
        grid-column: 10 / 13;
      }

      @media (max-width: 1080px) {
        .feature-showcase.feature-panel,
        .feature-showcase.feature-panel.feature-story-knowledge,
        .feature-showcase.feature-panel.feature-story-meeting {
          min-height: auto;
          grid-template-columns: 1fr;
          gap: 28px;
        }

        .feature-showcase.feature-panel .feature-copy-block,
        .feature-showcase.feature-panel.feature-story-knowledge .feature-copy-block,
        .feature-showcase.feature-panel.feature-story-meeting .feature-copy-block {
          height: auto;
        }

        .feature-showcase.feature-panel .feature-visual {
          min-height: 420px;
          height: auto;
        }

        .advisor-industry-map {
          min-height: 540px;
          grid-template-columns: repeat(12, minmax(0, 1fr));
          grid-template-rows: 38px 104px 48px 124px 54px;
        }

        .advisor-map-generic {
          grid-column: 1 / 5;
        }

        .advisor-map-not {
          grid-column: 5 / 6;
          justify-self: center;
        }

        .advisor-map-chenshu {
          grid-column: 6 / 13;
        }

        .advisor-map-more {
          display: none;
        }

        .advisor-map-brain {
          grid-column: 4 / 10;
        }

        .advisor-map-drawing {
          grid-column: 1 / 5;
        }

        .advisor-map-search {
          grid-column: 5 / 9;
        }

        .advisor-map-output {
          grid-column: 9 / 13;
        }

        .advisor-map-owner,
        .advisor-map-role {
          display: none;
        }

        .advisor-map-result {
          grid-column: 3 / 11;
        }
      }

      @media (max-width: 680px) {
        .feature-showcase-list {
          gap: 22px !important;
        }

        .feature-showcase.feature-panel,
        .feature-showcase.feature-panel.feature-story-knowledge,
        .feature-showcase.feature-panel.feature-story-meeting {
          padding: 24px 18px;
          gap: 22px;
          border-radius: 10px;
        }

        .feature-panel-kicker {
          margin-bottom: 14px;
          font-size: 13px;
        }

        .feature-showcase.feature-panel .feature-copy-block h3,
        .feature-showcase.feature-panel.feature-story-meeting .feature-copy-block h3 {
          max-width: 100%;
          margin-bottom: 16px;
          font-size: clamp(30px, 10.5vw, 38px);
        }

        .feature-showcase.feature-panel .feature-copy-block p,
        .feature-showcase.feature-panel.feature-story-meeting .feature-copy-block p {
          max-width: 100%;
          font-size: 15.5px;
          line-height: 1.72;
        }

        .feature-showcase.feature-panel .feature-emphasis {
          margin-top: 18px;
          font-size: 13px;
        }

        .feature-showcase.feature-panel .feature-capability-list,
        .feature-showcase.feature-panel.feature-story-knowledge .feature-capability-list,
        .feature-showcase.feature-panel.feature-story-meeting .feature-capability-list {
          grid-template-columns: 1fr;
          gap: 8px;
        }

        .feature-showcase.feature-panel .feature-capability-list li,
        .feature-showcase.feature-panel.feature-story-knowledge .feature-capability-list li,
        .feature-showcase.feature-panel.feature-story-meeting .feature-capability-list li,
        .feature-showcase.feature-panel.feature-story-meeting .feature-capability-list li:nth-child(odd),
        .feature-showcase.feature-panel.feature-story-meeting .feature-capability-list li:nth-child(even) {
          min-height: 66px;
          padding-block: 12px;
        }

        .feature-showcase.feature-panel .feature-visual,
        .feature-showcase.feature-panel.feature-story-knowledge .feature-visual,
        .feature-showcase.feature-panel.feature-story-meeting .feature-visual,
        .feature-showcase.feature-panel.feature-story-advisor .feature-visual {
          min-height: auto;
        }

        .advisor-industry-map {
          padding: 18px;
          grid-template-columns: 1fr;
          grid-template-rows: auto;
          gap: 10px;
        }

        .advisor-map-top,
        .advisor-map-generic,
        .advisor-map-not,
        .advisor-map-chenshu,
        .advisor-map-brain,
        .advisor-map-drawing,
        .advisor-map-search,
        .advisor-map-output,
        .advisor-map-result {
          grid-column: 1;
          grid-row: auto;
        }

        .advisor-map-not,
        .advisor-map-lines,
        .advisor-map-branch,
        .advisor-map-flow {
          display: none;
        }

        .advisor-map-capability {
          min-height: auto;
        }
      }
    `}</style>
  );
}

function ProductIntro() {
  const coreFeatures = ["advisor", "local", "knowledge", "meeting"]
    .map((id) => productFeatureShowcases.find((feature) => feature.id === id))
    .filter(Boolean);

  return (
    <section className="site-section intro-section" id="product">
      <FeatureShowcaseSkin />
      <div className="feature-showcase-list">
        {coreFeatures.map((feature) => (
          <article
            className={`feature-showcase feature-panel feature-story-${feature.id}`}
            id={`feature-${feature.id}`}
            key={feature.id}
            tabIndex={-1}
          >
            <div className="feature-copy-block">
              <div className="feature-panel-kicker">{feature.tag}</div>
              <h3>{feature.title}</h3>
              {feature.body.map((paragraph) => (
                <p key={paragraph}>{paragraph}</p>
              ))}
              <ul className="feature-capability-list">
                {feature.capabilities.map((capability) => {
                  const [capabilityName, capabilityDetail] = splitFeatureCapability(capability);
                  return (
                    <li key={capability}>
                      {capabilityDetail ? (
                        <>
                          <strong>{capabilityName}</strong>
                          <span>{capabilityDetail}</span>
                        </>
                      ) : (
                        capability
                      )}
                    </li>
                  );
                })}
              </ul>
              {feature.emphasis && <div className="feature-emphasis">{feature.emphasis}</div>}
            </div>
            <FeatureVisual feature={feature} />
          </article>
        ))}
      </div>
    </section>
  );
}

function ScenarioSection() {
  return (
    <section className="site-section scenario-section" id="scenarios">
      <div className="section-kicker">适用场景</div>
      <div className="two-column-head">
        <h2>从资料进场到交付复查，把环评用户最费时间的环节先接住。</h2>
        <p>
          ChenShu 不只回答“AI 能做什么”，而是让环评从业者一眼看到它能放进哪些真实工作节点。每个场景都以本地资料为基础，以用户确认为边界。
        </p>
      </div>
      <div className="scenario-grid">
        {scenarioCards.map((item) => (
          <article className="scenario-card" key={item.title}>
            <span>{item.label}</span>
            <h3>{item.title}</h3>
            <p>{item.body}</p>
            <strong>{item.result}</strong>
          </article>
        ))}
      </div>
    </section>
  );
}

function WorkflowSection() {
  return (
    <section className="site-section workflow-section" id="workflow">
      <div className="section-kicker">行业工作流</div>
      <div className="two-column-head">
        <h2>围绕环评项目推进，而不是让用户重新学习一套工具。</h2>
        <p>
          ChenShu 的目标不是让用户变成提示词专家，而是把 Agent 放进熟悉的环评工作路径里：资料接入、资料解析、任务推进、成果生成、核验复查、用户定稿，每一步都更清楚。
        </p>
      </div>
      <div className="workflow-grid">
        {workflowSteps.map(([num, title, body]) => (
          <article className="workflow-card" key={num}>
            <span>{num}</span>
            <h3>{title}</h3>
            <p>{body}</p>
          </article>
        ))}
      </div>
    </section>
  );
}

function DecisionSection() {
  return (
    <section className="site-section decision-section">
      <div className="decision-panel">
        <div>
          <div className="section-kicker">人机协作边界</div>
          <h2>Agent 可以执行很多事，但关键决定必须由用户确认。</h2>
          <p>
            环评工作里，数据、结论、引用和交付内容都关系到专业责任。ChenShu 在确保多工具自动化的同时，把关键事项的最终决定权交给用户，避免 Agent 越权生成、越权安装或替用户做专业判断。
          </p>
        </div>
        <ul className="decision-list">
          {decisionItems.map((item) => (
            <li key={item}>{item}</li>
          ))}
        </ul>
      </div>
    </section>
  );
}

function DownloadSection() {
  return (
    <section className="site-section download-section" id="download">
      <div className="download-copy">
        <div className="section-kicker">程序下载</div>
        <h2>开箱即用，第一次打开也知道下一步做什么。</h2>
        <p>
          用户无需花很长时间学习配置。打开 ChenShu 后，遇到使用问题可以直接提问；如果需要安装辅助程序或依赖，ChenShu Agent 会说明用途，并在用户确认后协助完成。
        </p>
        <div className="download-actions">
          <a className="solid-button" href={PRODUCT.downloadUrl}>进入下载中心</a>
          <button type="button" className="outline-button" onClick={() => window.scrollTo({ top: 0, behavior: "smooth" })}>
            查看产品介绍
          </button>
        </div>
      </div>
      <div className="download-card">
        <div className="download-card-head">
          <b>ChenShu Desktop</b>
          <span>{PRODUCT.version}</span>
        </div>
        {["Windows installer", "macOS universal", "Linux AppImage"].map((item) => (
          <a className="download-row" key={item} href={PRODUCT.downloadUrl}>
            <span>{item}</span>
            <small>下载</small>
          </a>
        ))}
      </div>
    </section>
  );
}

function Pricing({ actions }) {
  return (
    <section className="site-section pricing-section" id="pricing">
      <div className="section-kicker">产品价格</div>
      <div className="two-column-head">
        <h2>两种价格，一眼看懂；按项目节奏选择即可。</h2>
        <p>价格区分为年费 ¥299 和终身费 ¥599。官网购买流程采用虎皮椒支付：后端创建订单并接收支付回调，前端展示二维码和订单状态，支付确认后再发放授权。</p>
      </div>
      <div className="pricing-grid">
        {PLANS.map((plan) => (
          <article className={plan.id === "lifetime" ? "price-card featured" : "price-card"} key={plan.id}>
            <div className="plan-badge">{plan.badge}</div>
            <h3>{plan.name}</h3>
            <p>{plan.summary}</p>
            <div className="price-line">
              <span>¥</span>
              <strong>{plan.price}</strong>
              <small>{plan.suffix}</small>
            </div>
            <ul>
              {plan.features.map((feature) => (
                <li key={feature}>{feature}</li>
              ))}
            </ul>
            <button type="button" className="solid-button full" onClick={() => actions.openCheckout(plan)}>
              选择并支付
            </button>
          </article>
        ))}
      </div>
    </section>
  );
}

function AuthModal({ mode, onClose }) {
  const isLogin = mode === "login";
  if (!mode) return null;
  return (
    <div className="modal-backdrop" role="presentation" onMouseDown={onClose}>
      <section className="modal-card" role="dialog" aria-modal="true" aria-labelledby="auth-title" onMouseDown={(e) => e.stopPropagation()}>
        <button className="modal-close" type="button" aria-label="关闭" onClick={onClose}>×</button>
        <h2 id="auth-title">{isLogin ? "登录 ChenShu" : "注册 ChenShu"}</h2>
        <p>{isLogin ? "登录后可管理授权、下载记录和订单。" : "创建账号后可购买授权并接收下载与激活信息。"}</p>
        <form className="auth-form" onSubmit={(e) => { e.preventDefault(); onClose(); }}>
          {!isLogin && (
            <label>
              用户名
              <input required type="text" placeholder="你的名字" />
            </label>
          )}
          <label>
            邮箱
            <input required type="email" placeholder="name@example.com" />
          </label>
          <label>
            密码
            <input required type="password" placeholder="至少 8 位" minLength="8" />
          </label>
          <button className="solid-button full" type="submit">{isLogin ? "登录" : "创建账号"}</button>
        </form>
      </section>
    </div>
  );
}

function CheckoutModal({ plan, onClose, onComplete }) {
  const [method, setMethod] = React.useState("alipay");
  const [order, setOrder] = React.useState(null);
  const [status, setStatus] = React.useState("idle");
  const [statusText, setStatusText] = React.useState("");
  const [error, setError] = React.useState("");

  React.useEffect(() => {
    setMethod("alipay");
    setOrder(null);
    setStatus("idle");
    setStatusText("");
    setError("");
  }, [plan?.id]);

  React.useEffect(() => {
    if (!plan || !order?.orderId || order.status !== "pending") return undefined;
    let stopped = false;
    const poll = async () => {
      try {
        const response = await fetch(`${PAYMENT_API_BASE}/orders/${encodeURIComponent(order.orderId)}/status`);
        const nextOrder = await response.json();
        if (stopped) return;
        if (!response.ok) {
          setStatusText(nextOrder.error || "订单状态查询失败，稍后会继续自动查询。");
          return;
        }
        setOrder(nextOrder);
        if (nextOrder.status === "paid") {
          setStatus("paid");
          onComplete(plan, nextOrder);
        } else if (nextOrder.status === "cancelled") {
          setStatus("cancelled");
          setError("订单已取消，请重新创建支付订单。");
        } else if (nextOrder.lastQueryError) {
          setStatusText(`已创建订单，等待支付确认；最近一次查询提示：${nextOrder.lastQueryError}`);
        } else {
          setStatus("waiting");
          setStatusText("已创建虎皮椒订单，支付成功后系统会自动确认。");
        }
      } catch {
        if (!stopped) setStatusText("正在等待支付确认；网络暂时不可用时会继续轮询。");
      }
    };
    const first = window.setTimeout(poll, 1600);
    const timer = window.setInterval(poll, 5000);
    return () => {
      stopped = true;
      window.clearTimeout(first);
      window.clearInterval(timer);
    };
  }, [order?.orderId, order?.status, plan]);

  if (!plan) return null;

  const methodLabel = method === "wechat" ? "微信支付" : "支付宝";
  const canCreateOrder = status === "idle" || status === "error" || status === "cancelled";

  async function createOrder() {
    setStatus("creating");
    setStatusText("");
    setError("");
    try {
      const response = await fetch(`${PAYMENT_API_BASE}/orders`, {
        method: "POST",
        headers: { "content-type": "application/json" },
        body: JSON.stringify({ planId: plan.id, payType: method }),
      });
      const nextOrder = await response.json().catch(() => ({}));
      if (!response.ok) {
        throw new Error(nextOrder.error || "虎皮椒订单创建失败，请稍后重试。");
      }
      setOrder(nextOrder);
      if (nextOrder.status === "paid") {
        setStatus("paid");
        onComplete(plan, nextOrder);
      } else {
        setStatus("waiting");
        setStatusText("订单已提交到虎皮椒，请扫码支付。");
      }
    } catch (err) {
      setStatus("error");
      setError(err.message || "虎皮椒订单创建失败，请稍后重试。");
    }
  }

  async function refreshOrder() {
    if (!order?.orderId) return;
    setStatusText("正在向后端确认订单状态...");
    try {
      const response = await fetch(`${PAYMENT_API_BASE}/orders/${encodeURIComponent(order.orderId)}/status`);
      const nextOrder = await response.json().catch(() => ({}));
      if (!response.ok) {
        throw new Error(nextOrder.error || "订单状态查询失败。");
      }
      setOrder(nextOrder);
      if (nextOrder.status === "paid") {
        setStatus("paid");
        onComplete(plan, nextOrder);
      } else if (nextOrder.status === "cancelled") {
        setStatus("cancelled");
        setError("订单已取消，请重新创建支付订单。");
      } else {
        setStatus("waiting");
        setStatusText("尚未收到支付成功确认，请完成扫码支付。");
      }
    } catch (err) {
      setStatusText(err.message || "订单状态查询失败，稍后再试。");
    }
  }

  function resetOrder() {
    setOrder(null);
    setStatus("idle");
    setStatusText("");
    setError("");
  }

  return (
    <div className="modal-backdrop" role="presentation" onMouseDown={onClose}>
      <section className="modal-card checkout" role="dialog" aria-modal="true" aria-labelledby="checkout-title" onMouseDown={(e) => e.stopPropagation()}>
        <button className="modal-close" type="button" aria-label="关闭" onClick={onClose}>×</button>
        <h2 id="checkout-title">确认购买 {plan.name}</h2>
        <div className="order-summary">
          <span>订单金额</span>
          <strong>¥{plan.price}</strong>
          <small>{plan.suffix}</small>
        </div>
        <fieldset className="payment-methods">
          <legend>支付方式</legend>
          {[
            ["alipay", "虎皮椒 · 支付宝", "适合个人支付宝扫码付款"],
            ["wechat", "虎皮椒 · 微信支付", "如已开通微信渠道可启用"],
          ].map(([id, label]) => (
            <label key={id} className={method === id ? "selected" : ""}>
              <input disabled={Boolean(order)} type="radio" name="payment" value={id} checked={method === id} onChange={() => setMethod(id)} />
              <span>
                <strong>{label}</strong>
                <small>{id === "alipay" ? "适合个人支付宝扫码付款" : "如已开通微信渠道可启用"}</small>
              </span>
            </label>
          ))}
        </fieldset>
        {order && (
          <div className="payment-order-panel">
            <div className="payment-order-head">
              <span className={order.status === "paid" ? "status-pill paid" : "status-pill"}>
                {order.status === "paid" ? "已支付" : "待支付"}
              </span>
              <small>订单号：{order.orderId}</small>
            </div>
            {order.qrCodeUrl ? (
              <div className="payment-qr">
                <img src={order.qrCodeUrl} alt={`${methodLabel}支付二维码`} />
                <p>请使用{methodLabel}扫码支付，二维码有效期约五分钟。</p>
              </div>
            ) : (
              <div className="payment-link-box">
                <p>虎皮椒已返回支付链接，请点击打开支付页面。</p>
              </div>
            )}
            <div className="payment-actions">
              {order.paymentUrl && (
                <a className="outline-button" href={order.paymentUrl} target="_blank" rel="noreferrer">
                  打开支付页
                </a>
              )}
              <button className="outline-button" type="button" onClick={refreshOrder}>
                刷新状态
              </button>
              <button className="text-button" type="button" onClick={resetOrder}>
                重新下单
              </button>
            </div>
          </div>
        )}
        {statusText && <p className="checkout-status">{statusText}</p>}
        {error && <p className="checkout-error">{error}</p>}
        {canCreateOrder && (
          <button className="solid-button full" type="button" onClick={createOrder}>
            创建虎皮椒订单 ¥{plan.price}
          </button>
        )}
        {status === "creating" && (
          <button className="solid-button full" type="button" disabled>
            正在创建虎皮椒订单...
          </button>
        )}
        <p className="modal-note">支付确认以虎皮椒 notify_url 回调和订单查询结果为准。APPID 与 SECRET 只保存在后端，不能写入静态网页。</p>
      </section>
    </div>
  );
}

function PaidModal({ plan, onClose }) {
  if (!plan) return null;
  const order = plan.order;
  return (
    <div className="modal-backdrop" role="presentation" onMouseDown={onClose}>
      <section className="modal-card" role="dialog" aria-modal="true" aria-labelledby="paid-title" onMouseDown={(e) => e.stopPropagation()}>
        <button className="modal-close" type="button" aria-label="关闭" onClick={onClose}>×</button>
        <h2 id="paid-title">支付已确认</h2>
        <p>你选择了 {plan.name}，金额 ¥{plan.price}。后端确认订单支付后，即可发放 ChenShu 授权并引导用户下载程序。</p>
        {order && (
          <dl className="receipt-list">
            <div>
              <dt>订单号</dt>
              <dd>{order.orderId}</dd>
            </div>
            <div>
              <dt>支付通道</dt>
              <dd>{order.payType === "wechat" ? "虎皮椒 · 微信支付" : "虎皮椒 · 支付宝"}</dd>
            </div>
            {order.transactionId && (
              <div>
                <dt>交易号</dt>
                <dd>{order.transactionId}</dd>
              </div>
            )}
          </dl>
        )}
        <a className="solid-button full" href={PRODUCT.downloadUrl}>前往下载</a>
      </section>
    </div>
  );
}

function FAQ() {
  const items = [
    ["ChenShu 和通用 AI 办公产品有什么不同？", "ChenShu 面向环境影响评价行业设计，强调本地资料处理、行业工作流嵌入和用户确认机制，而不是只提供通用问答。"],
    ["资料一定不会上传云端吗？", "ChenShu 的资料解析和处理默认在本地电脑完成，不需要把项目文件上传到云端处理。涉及外部联网能力或第三方服务时，也应由用户确认后再执行。"],
    ["适合哪些环评用户？", "适合环评工程师、项目负责人、技术团队和长期承接环评项目的机构用户，尤其适合资料多、节点紧、需要反复核验的项目。"],
    ["可以处理多少资料？", "ChenShu 采用本地工作区方式处理资料，不以云端上传次数作为主要限制。实际体验会受电脑性能、资料规模和文件类型影响。"],
    ["不会安装或不会使用怎么办？", "ChenShu 目标是开箱即用。遇到使用问题可以直接询问 Agent；需要安装辅助程序时，也会说明原因并在用户确认后协助完成。"],
    ["Agent 会不会自动替我做专业判断？", "不会。涉及文档生成、依赖安装、资料解析、数据准确性等关键事项时，ChenShu 会把决定权交给用户。"],
  ];
  return (
    <section className="site-section faq-section" id="faq">
      <div className="section-kicker">FAQ</div>
      <div className="faq-grid">
        {items.map(([q, a]) => (
          <article key={q}>
            <h3>{q}</h3>
            <p>{a}</p>
          </article>
        ))}
      </div>
    </section>
  );
}

function SiteFooter() {
  return (
    <footer className="site-footer">
      <div>
        <strong>{PRODUCT.name}</strong>
        <p>面向环境影响评价行业的本地优先 AI 工作台。</p>
      </div>
      <nav aria-label="页脚导航">
        <a href="#product">产品</a>
        <a href="#workflow">流程</a>
        <a href="manual.html">操作手册</a>
        <a href="download.html">下载</a>
        <a href="#faq">FAQ</a>
      </nav>
    </footer>
  );
}

function App() {
  const modal = useModalState();
  return (
    <>
      <SiteNav actions={modal} />
      <main>
        <Hero actions={modal} />
        <ProductIntro />
        <WorkflowSection />
        <DecisionSection />
        <FAQ />
      </main>
      <SiteFooter />
      <AuthModal mode={modal.authMode} onClose={modal.closeAuth} />
      <CheckoutModal plan={modal.checkoutPlan} onClose={modal.closeCheckout} onComplete={modal.completePayment} />
      <PaidModal plan={modal.paidPlan} onClose={modal.closePaid} />
    </>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
