---
import ComponentDemo from '../components/ComponentDemo.astro';

const CLARITY_ID = import.meta.env.PUBLIC_CLARITY_ID ?? '';
const WAITLIST_ENDPOINT = import.meta.env.PUBLIC_WAITLIST_ENDPOINT ?? '';
const releasesUrl = 'https://github.com/TouchAI-org/TouchAI/releases';
const repoUrl = 'https://github.com/TouchAI-org/TouchAI';
const docsUrl = 'https://touch-ai.org/getting-started';
---

<!doctype html>
<html lang="zh-CN">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>TouchAI</title>
        <meta
            name="description"
            content="TouchAI 是一款桌面效率 Agent，连接文件、上下文、命令和工具，让工作流更顺手。"
        />
        <meta name="keywords" content="TouchAI, 桌面 AI, AI 助手, MCP, BYOK, 效率工具" />
        <meta name="author" content="TouchAI" />
        <meta property="og:type" content="website" />
        <meta property="og:title" content="TouchAI" />
        <meta property="og:description" content="一触即达的桌面效率Agent" />
        <meta property="og:url" content="https://touch-ai.org/" />
        <meta property="og:site_name" content="TouchAI" />
        <meta name="twitter:card" content="summary_large_image" />
        <meta name="twitter:title" content="TouchAI" />
        <meta name="twitter:description" content="一触即达的桌面效率Agent" />
        <link rel="icon" type="image/x-icon" href="/favicon.ico" />
        <link rel="shortcut icon" href="/favicon.ico" />
        <link rel="apple-touch-icon" href="/touchai-wordmark.svg" />
        <meta name="theme-color" content="#ffffff" />
        {
            CLARITY_ID && (
                <script
                    is:inline
                    set:html={`(function(c,l,a,r,i,t,y){c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)};t=l.createElement(r);t.async=1;t.src='https://www.clarity.ms/tag/'+i;y=l.getElementsByTagName(r)[0];y.parentNode.insertBefore(t,y)})(window,document,'clarity','script','${CLARITY_ID}');`}
                />
            )
        }
        <style is:global>
            :root {
                --bg: #ffffff;
                --ink: #111111;
                --muted: #5f5f5f;
                --line: #e4e4e7;
                --soft: #f4f4f5;
                --soft-2: #fffefa;
                --nav-bg: transparent;
                --dark: #101014;
                --feature-copy-surface: linear-gradient(180deg, #e9ebef 0%, #dfe3e8 100%);
                --feature-media-surface: linear-gradient(180deg, #fbfcfd 0%, #f1f3f6 100%);
                --feature-component-bg:
                    radial-gradient(circle at 18% 24%, rgba(74, 156, 255, 0.16), transparent 42%),
                    radial-gradient(circle at 78% 22%, rgba(255, 105, 180, 0.12), transparent 44%),
                    radial-gradient(circle at 52% 82%, rgba(255, 210, 92, 0.14), transparent 48%),
                    linear-gradient(135deg, #ffffff 0%, #f8fbff 50%, #fff8fb 100%);
                --feature-shell-bg: linear-gradient(132deg, #ffffff 0%, #fffefa 46%, #f3faff 100%);
                --component-stage-bg:
                    radial-gradient(circle at 19% 71%, rgba(74, 156, 255, 0.2), transparent 28%),
                    radial-gradient(circle at 72% 12%, rgba(74, 156, 255, 0.14), transparent 25%),
                    linear-gradient(132deg, #ffffff 0%, #fffefa 46%, #f3faff 100%);
                --max: 1180px;
                --font-serif:
                    'Source Han Serif SC', 'Source Han Serif CN', 'Noto Serif SC', 'Songti SC',
                    'SimSun', serif;
                --text-nav: 15px;
                --text-button: 15px;
                --text-caption: 15px;
                --text-body: 18px;
                --text-body-lg: 20px;
                --text-card-title: 27px;
            }

            html[data-theme='dark'] {
                --bg: #09090b;
                --ink: #fafafa;
                --muted: #a1a1aa;
                --line: #27272a;
                --soft: #18181b;
                --soft-2: #27272a;
                --nav-bg: transparent;
                --feature-copy-surface: linear-gradient(180deg, #2f3137 0%, #24262b 100%);
                --feature-media-surface: linear-gradient(180deg, #eef0f3 0%, #dfe3e8 100%);
                --feature-component-bg:
                    radial-gradient(circle at 18% 24%, rgba(74, 156, 255, 0.14), transparent 42%),
                    radial-gradient(circle at 78% 22%, rgba(255, 105, 180, 0.1), transparent 44%),
                    radial-gradient(circle at 52% 82%, rgba(255, 210, 92, 0.08), transparent 48%),
                    linear-gradient(135deg, #09090b 0%, #0d1118 50%, #120d14 100%);
                --feature-shell-bg: linear-gradient(132deg, #09090b 0%, #0a0b0f 52%, #0f1318 100%);
                --component-stage-bg:
                    radial-gradient(circle at 19% 71%, rgba(70, 86, 105, 0.14), transparent 29%),
                    radial-gradient(circle at 72% 12%, rgba(54, 68, 84, 0.1), transparent 25%),
                    linear-gradient(132deg, #09090b 0%, #0a0b0f 52%, #0f1318 100%);
                color-scheme: dark;
            }

            * {
                box-sizing: border-box;
            }

            [hidden] {
                display: none !important;
            }

            html {
                scroll-behavior: auto;
            }

            section[id] {
                scroll-margin-top: 92px;
            }

            body {
                margin: 0;
                background: var(--bg);
                color: var(--ink);
                font-family: var(--font-serif);
                -webkit-font-smoothing: antialiased;
                text-rendering: optimizeLegibility;
                overflow-x: hidden;
            }

            a {
                color: inherit;
                text-decoration: none;
            }

            img {
                display: block;
                max-width: 100%;
            }

            .nav {
                position: sticky;
                top: 0;
                z-index: 20;
                display: grid;
                grid-template-columns: 1fr 1fr;
                align-items: center;
                width: 100%;
                min-height: 72px;
                margin: 0 auto;
                padding: 0 24px;
                background: var(--nav-bg);
                backdrop-filter: none;
                transition:
                    background-color 0.2s ease,
                    box-shadow 0.2s ease,
                    backdrop-filter 0.2s ease;
            }

            .nav::after {
                content: '';
                position: absolute;
                left: 0;
                right: 0;
                bottom: -24px;
                height: 24px;
                pointer-events: none;
                opacity: 0;
                background: linear-gradient(
                    180deg,
                    rgba(255, 255, 255, 0.28) 0%,
                    rgba(255, 255, 255, 0) 100%
                );
                transition: opacity 0.2s ease;
            }

            .nav.is-scrolled {
                background: rgba(255, 255, 255, 0.94);
                backdrop-filter: blur(14px);
                box-shadow: none;
            }

            html[data-theme='dark'] .nav.is-scrolled {
                background: rgba(9, 9, 11, 0.94);
            }

            html[data-theme='dark'] .nav::after {
                background: linear-gradient(
                    180deg,
                    rgba(9, 9, 11, 0.72) 0%,
                    rgba(9, 9, 11, 0) 100%
                );
            }

            .nav.is-scrolled::after {
                opacity: 1;
            }

            .logo-link {
                display: inline-flex;
                align-items: center;
                justify-self: start;
                justify-content: flex-start;
                width: max-content;
            }

            .wordmark {
                width: 150px;
                height: auto;
            }

            html[data-theme='dark'] .wordmark {
                content: url('/touchai-wordmark-light.svg');
            }

            .nav-actions {
                display: flex;
                align-items: center;
                gap: 26px;
                font-size: var(--text-nav);
                font-weight: 600;
                line-height: 1;
            }

            .nav-actions {
                justify-content: flex-end;
            }

            .nav-icon-link {
                width: 28px;
                height: 28px;
                display: inline-flex;
                align-items: center;
                justify-content: center;
                transition: transform 0.16s ease;
                will-change: transform;
            }

            .nav-icon-link svg {
                width: 20px;
                height: 20px;
                stroke-width: 1.9;
            }

            .lang-toggle {
                position: relative;
                width: 28px;
                height: 28px;
                border: 0;
                padding: 0;
                display: inline-flex;
                align-items: center;
                justify-content: center;
                gap: 0;
                color: var(--ink);
                background: transparent;
                font: inherit;
                font-weight: 600;
                line-height: 1;
                cursor: pointer;
                transition: transform 0.16s ease;
                will-change: transform;
            }

            .theme-toggle {
                width: 28px;
                height: 28px;
                border: 0;
                padding: 0;
                display: inline-flex;
                align-items: center;
                justify-content: center;
                color: var(--ink);
                background: transparent;
                cursor: pointer;
                transition: transform 0.16s ease;
                will-change: transform;
            }

            .theme-toggle svg {
                width: 20px;
                height: 20px;
                stroke-width: 1.9;
            }

            .theme-toggle .sun-icon {
                display: none;
            }

            html[data-theme='dark'] .theme-toggle .moon-icon {
                display: none;
            }

            html[data-theme='dark'] .theme-toggle .sun-icon {
                display: block;
            }

            .lang-toggle svg {
                width: 18px;
                height: 18px;
                stroke-width: 1.8;
            }

            .lang-toggle span {
                position: absolute;
                width: 1px;
                height: 1px;
                overflow: hidden;
                clip: rect(0, 0, 0, 0);
                white-space: nowrap;
            }

            .lang-toggle:hover,
            .theme-toggle:hover {
                text-decoration: underline;
                text-underline-offset: 5px;
            }

            .nav a:hover {
                text-decoration: underline;
                text-underline-offset: 5px;
            }

            .hero {
                position: relative;
                isolation: isolate;
                overflow: hidden;
                width: 100%;
                max-width: none;
                margin: 0;
                min-height: calc(100dvh - 72px);
                padding: 32px 24px 40px;
                display: flex;
                flex-direction: column;
                justify-content: center;
                text-align: center;
                background: var(--bg);
                background-image: none;
            }

            .hero::before,
            .hero::after {
                content: none !important;
                display: none !important;
            }

            .hero h1 {
                margin: 0;
                line-height: 1;
            }

            .hero-wordmark {
                width: min(72vw, 640px);
                height: auto;
                margin: 0 auto;
            }

            html[data-theme='dark'] .hero-wordmark {
                content: url('/touch-ai-hero-dark.svg?v=3');
            }

            .hero-subtitle {
                max-width: 820px;
                margin: 24px auto 0;
                color: var(--ink);
                font-size: clamp(28px, 3.1vw, 42px);
                font-weight: 500;
                line-height: 1.22;
                letter-spacing: 0;
            }

            .hero-actions {
                display: flex;
                flex-wrap: wrap;
                justify-content: center;
                gap: 14px;
                margin-top: 28px;
            }

            .button {
                position: relative;
                display: inline-flex;
                align-items: center;
                justify-content: center;
                min-height: 46px;
                padding: 0 22px;
                border: 1px solid var(--ink);
                border-radius: 999px;
                background: var(--ink);
                color: var(--bg);
                font-family: var(--font-serif);
                font-size: var(--text-button);
                font-weight: 600;
                line-height: 1;
                white-space: nowrap;
                overflow: hidden;
                transition:
                    background 0.2s ease,
                    color 0.2s ease,
                    border-color 0.2s ease,
                    transform 0.16s ease;
                will-change: transform;
            }

            .interactive-click {
                position: relative;
                display: inline-flex;
                align-items: center;
                justify-content: center;
                overflow: hidden;
                isolation: isolate;
                transition:
                    color 0.2s ease,
                    background 0.2s ease,
                    border-color 0.2s ease,
                    transform 0.16s ease;
                will-change: transform;
            }

            .logo-link.interactive-click {
                justify-content: flex-start;
                width: max-content;
            }

            .nav-icon-link,
            .lang-toggle,
            .theme-toggle {
                position: relative;
                overflow: hidden;
                border-radius: 999px;
            }

            .interactive-click > * {
                position: relative;
                z-index: 1;
            }

            .button:hover {
                transform: translateY(-1px);
            }

            .interactive-click.is-pressing {
                transform: scale(0.94);
            }

            .button.secondary {
                background: var(--bg);
                color: var(--ink);
            }

            .glimm-click-layer {
                position: fixed;
                inset: 0;
                z-index: 9999;
                width: 100vw;
                height: 100vh;
                pointer-events: none;
            }

            body.is-glimm-transitioning .interactive-click {
                pointer-events: none;
            }

            .visual-section {
                width: min(calc(100% - 48px), var(--max));
                margin: 0 auto;
                min-height: 100svh;
            }

            .visual-shell {
                position: relative;
                overflow: visible;
                border-radius: 14px;
                background: var(--bg);
                box-shadow: none;
                min-height: 100svh;
                display: grid;
                align-items: center;
            }

            .visual-stage {
                width: 100%;
                height: 100svh;
                min-height: 780px;
                background: var(--bg);
                display: grid;
                align-items: center;
                justify-items: center;
                overflow: visible;
            }

            .visual-shell,
            .visual-stage,
            .component-frame {
                transition: background-color 0.2s ease;
            }

            .visual-stage-inner {
                width: 100%;
                height: 100%;
            }

            touchai-component-demo {
                --page-bg: var(--component-stage-bg);
            }

            .component-frame {
                --page-bg: transparent;
                display: block;
                width: min(60vw, 680px, 100%);
                max-width: 680px;
                height: 100%;
                min-height: 0;
                border: 0;
                background: transparent;
                justify-self: center;
            }

            .section {
                width: min(calc(100% - 48px), var(--max));
                margin: 0 auto;
                padding: 92px 0;
            }

            .section-title {
                max-width: 900px;
                margin: 0 0 46px;
                font-size: clamp(38px, 5.8vw, 72px);
                font-weight: 600;
                line-height: 1.12;
                letter-spacing: 0;
            }

            .feature-stack {
                display: grid;
                gap: 20px;
            }

            .feature-block {
                position: relative;
                min-height: clamp(1500px, 220vh, 2100px);
            }

            .feature-block-shell {
                position: sticky;
                top: calc(50vh - 280px);
                display: grid;
                grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr);
                min-height: 560px;
                overflow: visible;
                border-radius: 28px;
                background: transparent;
                align-items: stretch;
            }

            .feature-block.reverse .feature-block-shell {
                grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr);
            }

            .feature-copy {
                display: flex;
                flex-direction: column;
                justify-content: center;
                gap: 38px;
                padding: clamp(24px, 4vw, 40px);
                min-height: 560px;
                background: var(--feature-copy-surface);
                overflow: hidden;
            }

            .feature-block .feature-copy:first-child,
            .feature-block .feature-media:first-child {
                border-radius: 28px 0 0 28px;
            }

            .feature-block .feature-copy:last-child,
            .feature-block .feature-media:last-child {
                border-radius: 0 28px 28px 0;
            }

            .feature-copy h3 {
                width: 100%;
                max-width: 500px;
                margin: 0;
                font-size: clamp(28px, 3.5vw, 44px);
                font-weight: 600;
                line-height: 1.18;
                text-align: left;
                letter-spacing: 0;
            }

            .feature-copy p {
                width: 100%;
                max-width: 500px;
                margin: 0;
                color: var(--muted);
                font-size: var(--text-body);
                line-height: 1.7;
                text-align: justify;
                text-align-last: left;
                letter-spacing: 0;
            }

            html[lang='en'] .feature-copy p {
                text-align: left;
            }

            .feature-media {
                display: grid;
                place-items: center;
                min-height: 560px;
                padding: 18px;
                background: var(--feature-media-surface);
                overflow: visible;
            }

            .feature-media.solver-media {
                padding: 0;
            }

            .feature-media.work-media,
            .feature-media.reminder-media {
                padding: 0;
            }

            .feature-block.reverse .feature-copy {
                background: var(--feature-media-surface);
                color: #111111;
            }

            .feature-block.reverse .feature-copy p {
                color: #5f6368;
            }

            .feature-block.reverse .feature-media {
                background: var(--feature-copy-surface);
            }

            .phone-card,
            .code-card {
                width: min(100%, 520px);
                border: 0;
                border-radius: 18px;
                background: transparent;
                box-shadow: none;
                overflow: hidden;
            }

            .feature-component-card {
                --component-scale: 0.62;
                --component-shell-height: 657px;
                --embedded-frame-height: var(--component-shell-height);
                --page-bg: var(--feature-shell-bg);
                width: min(100%, calc(760px * var(--component-scale)));
                height: calc(var(--component-shell-height) * var(--component-scale));
                padding: 0;
                border: 0;
                position: relative;
                border-radius: 0;
                background: transparent;
                box-shadow: none;
                overflow: visible;
                justify-self: center;
                align-self: center;
                cursor: pointer;
            }

            .feature-component-frame {
                --embedded-frame-height: 657px;
                display: block;
                width: 760px;
                height: 657px !important;
                min-height: 657px !important;
                max-height: 657px !important;
                border: 0;
                background: transparent !important;
                position: absolute;
                z-index: 0;
                top: 50%;
                left: 50%;
                transform: translate(-50%, -50%) scale(var(--component-scale));
                transform-origin: center center;
                border-radius: 0;
                pointer-events: none;
            }

            .feature-work-card {
                --component-scale: 0.62;
                --component-shell-height: 657px;
                --embedded-frame-height: var(--component-shell-height);
                --page-bg: var(--feature-shell-bg);
                width: min(100%, calc(760px * var(--component-scale)));
                height: calc(var(--component-shell-height) * var(--component-scale));
                padding: 0;
                border: 0;
                position: relative;
                border-radius: 0;
                background: transparent;
                box-shadow: none;
                overflow: visible;
                justify-self: center;
                align-self: center;
                cursor: pointer;
            }

            .feature-work-frame {
                --embedded-frame-height: 657px;
                display: block;
                width: 760px;
                height: 657px !important;
                min-height: 657px !important;
                max-height: 657px !important;
                border: 0;
                background: transparent !important;
                position: absolute;
                z-index: 0;
                top: 50%;
                left: 50%;
                transform: translate(-50%, -50%) scale(var(--component-scale));
                transform-origin: center center;
                border-radius: 0;
                pointer-events: none;
            }

            .feature-reminder-card {
                --component-scale: 0.62;
                --component-shell-height: 657px;
                --embedded-frame-height: var(--component-shell-height);
                --page-bg: var(--feature-shell-bg);
                width: min(100%, calc(760px * var(--component-scale)));
                height: calc(var(--component-shell-height) * var(--component-scale));
                padding: 0;
                border: 0;
                position: relative;
                border-radius: 0;
                background: transparent;
                box-shadow: none;
                overflow: visible;
                justify-self: center;
                align-self: center;
                cursor: pointer;
            }

            .feature-reminder-frame {
                --embedded-frame-height: 657px;
                display: block;
                width: 760px;
                height: 657px !important;
                min-height: 657px !important;
                max-height: 657px !important;
                border: 0;
                background: transparent !important;
                position: absolute;
                z-index: 0;
                top: 50%;
                left: 50%;
                transform: translate(-50%, -50%) scale(var(--component-scale));
                transform-origin: center center;
                border-radius: 0;
                pointer-events: none;
            }

            .code-card {
                padding: 24px;
                background: rgba(12, 12, 15, 0.88);
                color: #e8e8e8;
                font-size: 15px;
                line-height: 1.8;
            }

            .code-card span {
                color: #8ab4ff;
            }

            .scenario-grid {
                display: grid;
                grid-template-columns: repeat(3, minmax(0, 1fr));
                gap: 16px;
                perspective: 1100px;
            }

            .scenario-card {
                position: relative;
                min-height: 360px;
                padding: 28px;
                border-radius: 28px;
                background: #eeece6;
                color: #151515;
                overflow: hidden;
                transform-style: preserve-3d;
                will-change: transform, opacity;
                transition:
                    background-color 0.28s ease,
                    color 0.28s ease,
                    box-shadow 0.28s ease;
            }

            html[data-theme='dark'] .scenario-card {
                background: #eeece6;
                color: #151515;
            }

            .scenario-grid .scenario-card:hover {
                background: #eeece6;
                color: #151515;
                box-shadow: 0 18px 42px rgba(0, 0, 0, 0.22);
            }

            .scenario-grid:hover .scenario-card:not(:hover) {
                background: #eeece6;
                color: #151515;
                box-shadow: none;
            }

            html[data-theme='dark'] .scenario-grid .scenario-card:hover {
                background: #eeece6;
                color: #151515;
                box-shadow: 0 18px 42px rgba(0, 0, 0, 0.22);
            }

            html[data-theme='dark'] .scenario-grid:hover .scenario-card:not(:hover) {
                background: #eeece6;
                color: #151515;
                box-shadow: none;
            }

            .scenario-card::before {
                content: '';
                position: absolute;
                inset: -1px;
                z-index: 0;
                border-radius: inherit;
                opacity: var(--scenario-glow-opacity, 0);
                background:
                    radial-gradient(
                        circle at var(--scenario-glow-x, 50%) var(--scenario-glow-y, 50%),
                        rgba(118, 179, 255, 0.34),
                        transparent 34%
                    ),
                    linear-gradient(135deg, rgba(255, 255, 255, 0.22), transparent 42%);
                transition: opacity 0.24s ease;
                pointer-events: none;
            }

            .scenario-card::after {
                content: '';
                position: absolute;
                inset: 0;
                z-index: 0;
                border-radius: inherit;
                opacity: var(--scenario-shine-opacity, 0);
                background: linear-gradient(
                    110deg,
                    transparent 0%,
                    rgba(255, 255, 255, 0.34) 43%,
                    rgba(255, 255, 255, 0.12) 50%,
                    transparent 58%
                );
                transform: translateX(var(--scenario-shine-x, -120%));
                pointer-events: none;
            }

            .scenario-card > * {
                position: relative;
                z-index: 1;
            }

            .scenario-card h3 {
                margin: 0 0 18px;
                font-size: var(--text-card-title);
                font-weight: 600;
                line-height: 1.26;
                letter-spacing: 0;
            }

            .scenario-card p {
                margin: 0;
                color: #55514c;
                font-size: var(--text-body);
                line-height: 1.7;
                transition: color 0.28s ease;
            }

            .scenario-grid .scenario-card:hover p {
                color: #55514c;
            }

            html[data-theme='dark'] .scenario-card p {
                color: #55514c;
            }

            html[data-theme='dark'] .scenario-grid .scenario-card:hover p {
                color: #55514c;
            }

            html[data-theme='dark'] .scenario-grid:hover .scenario-card:not(:hover) p {
                color: #55514c;
            }

            .github-feedback-head {
                display: flex;
                align-items: end;
                justify-content: space-between;
                gap: 28px;
                margin-bottom: 46px;
            }

            .github-feedback-head .section-title {
                margin: 0;
            }

            .github-stats {
                display: flex;
                gap: 10px;
                flex-wrap: nowrap;
                justify-content: flex-end;
                align-items: stretch;
            }

            .github-stat {
                min-width: 96px;
                padding: 12px 14px;
                border: 1px solid var(--line);
                border-radius: 8px;
                background: var(--soft);
            }

            .github-stat strong {
                display: block;
                font-size: 22px;
                line-height: 1;
            }

            .github-stat span {
                display: block;
                margin-top: 8px;
                color: var(--muted);
                font-size: 13px;
                line-height: 1.2;
            }

            .quote-row.review-grid {
                display: grid;
                grid-template-columns: repeat(4, minmax(0, 1fr));
                gap: 14px;
            }

            .review-card {
                position: relative;
                min-height: 240px;
                padding: 18px;
                border: 1px solid var(--line);
                border-radius: 18px;
                background: var(--soft);
                box-shadow: 0 10px 28px rgba(0, 0, 0, 0.06);
                display: flex;
                flex-direction: column;
                justify-content: space-between;
                gap: 14px;
                overflow: hidden;
            }

            html[data-theme='dark'] .review-card {
                background: var(--soft);
                border-color: rgba(255, 255, 255, 0.07);
            }

            .review-card-content {
                display: flex;
                flex-direction: column;
                gap: 12px;
                height: 100%;
            }

            .review-card-top {
                display: flex;
                align-items: center;
                gap: 12px;
            }

            .review-avatar-link {
                flex: 0 0 auto;
                border-radius: 50%;
            }

            .review-avatar {
                width: 38px;
                height: 38px;
                flex: 0 0 auto;
                border-radius: 50%;
                border: 1px solid var(--line);
                object-fit: cover;
                background: #fff;
            }

            .review-avatar-link:hover .review-avatar,
            .review-avatar-link:focus-visible .review-avatar {
                border-color: var(--ink);
            }

            .review-title-block {
                display: flex;
                flex-direction: column;
                gap: 2px;
                min-width: 0;
                align-items: flex-start;
            }

            .review-title-row {
                display: flex;
                align-items: center;
                gap: 10px;
                font-size: 14px;
                line-height: 1.2;
            }

            .review-title-row strong {
                color: var(--ink);
                font-size: 15px;
                font-weight: 600;
            }

            .review-author-link:hover,
            .review-author-link:focus-visible {
                text-decoration: underline;
                text-underline-offset: 4px;
            }

            .review-handle,
            .review-platform {
                color: var(--muted);
                font-size: 12px;
            }

            .review-handle {
                display: block;
                text-align: left;
            }

            .review-divider {
                display: none;
            }

            .review-card p {
                margin: 0;
                font-size: 18px;
                line-height: 1.65;
                letter-spacing: 0;
                color: var(--ink);
            }

            @media (max-width: 1120px) {
                .quote-row.review-grid {
                    grid-template-columns: repeat(2, minmax(0, 1fr));
                }
            }

            @media (max-width: 720px) {
                .quote-row.review-grid {
                    grid-template-columns: 1fr;
                }
            }

            .cta {
                width: min(calc(100% - 48px), 920px);
                margin: 0 auto 72px;
                padding: clamp(38px, 6vw, 68px);
                border-radius: 24px;
                background: var(--ink);
                color: var(--bg);
                text-align: center;
            }

            .cta h2 {
                max-width: 900px;
                margin: 0 auto;
                font-size: clamp(38px, 6.6vw, 82px);
                font-weight: 600;
                line-height: 1.12;
                letter-spacing: 0;
            }

            .cta p {
                max-width: 680px;
                margin: 28px auto 0;
                color: #d0d0d0;
                font-size: var(--text-body-lg);
                line-height: 1.6;
            }

            html[data-theme='dark'] .cta p {
                color: rgba(17, 17, 17, 0.68);
            }

            .cta .button {
                margin-top: 34px;
                border-color: var(--bg);
            }

            .footer {
                width: min(calc(100% - 48px), var(--max));
                margin: 0 auto;
                padding: 32px 0;
                border-top: 1px solid var(--line);
                color: var(--muted);
                font-size: 14px;
                line-height: 1.6;
                text-align: center;
                display: flex;
                flex-direction: column;
                align-items: center;
                gap: 10px;
            }

            .footer-links {
                display: flex;
                align-items: center;
                justify-content: center;
                gap: 22px;
                color: var(--muted);
                font-size: 14px;
                line-height: 1.4;
            }

            .footer-links a {
                color: var(--muted);
            }

            .footer-links a:hover,
            .footer-links a:focus-visible {
                text-decoration: underline;
                text-underline-offset: 4px;
            }

            @media (max-width: 900px) {
                .nav {
                    grid-template-columns: auto 1fr;
                    min-height: 64px;
                    gap: 12px;
                    padding: 0 18px;
                }

                .nav-actions {
                    justify-content: flex-end;
                    gap: 14px;
                }

                .hero {
                    min-height: calc(100dvh - 64px);
                    padding: 28px 18px 34px;
                }

                .visual-section {
                    min-height: auto;
                    padding: 48px 0 64px;
                }

                .visual-shell {
                    min-height: auto;
                    display: block;
                    padding: 24px 0;
                }

                .visual-stage {
                    height: auto;
                    min-height: auto;
                    display: grid;
                    place-items: center;
                    overflow: visible;
                }

                .component-frame {
                    width: min(60vw, 520px, 100%);
                    height: auto;
                    aspect-ratio: 760 / 657;
                    max-height: min(62vh, 657px);
                    min-height: 0;
                }

                .feature-block-shell,
                .scenario-grid,
                .quote-row {
                    grid-template-columns: 1fr;
                }

                .feature-block {
                    min-height: auto;
                    padding: 0;
                }

                .feature-block-shell {
                    position: static;
                    top: auto;
                    grid-template-columns: 1fr;
                    min-height: auto;
                    gap: 0;
                    overflow: hidden;
                    border-radius: 22px;
                }

                .feature-block.reverse .feature-block-shell {
                    grid-template-columns: 1fr;
                }

                .feature-block.reverse .feature-media {
                    order: 2;
                }

                .feature-block.reverse .feature-copy {
                    order: 1;
                }

                .feature-copy,
                .feature-media {
                    min-height: auto;
                }

                .feature-block .feature-copy:first-child,
                .feature-block .feature-media:first-child,
                .feature-block .feature-copy:last-child,
                .feature-block .feature-media:last-child {
                    border-radius: 0;
                }

                .feature-block:not(.reverse) .feature-copy,
                .feature-block.reverse .feature-copy {
                    border-radius: 22px 22px 0 0;
                }

                .feature-block:not(.reverse) .feature-media,
                .feature-block.reverse .feature-media {
                    border-radius: 0 0 22px 22px;
                }

                .feature-copy {
                    gap: 20px;
                    padding: 28px;
                    align-items: flex-start;
                }

                .feature-copy h3,
                .feature-copy p {
                    max-width: none;
                }

                .feature-media {
                    min-height: 430px;
                    padding: 22px 0 30px;
                    border-radius: 0;
                    overflow: hidden;
                }

                .feature-component-card,
                .feature-work-card,
                .feature-reminder-card {
                    width: min(100%, 520px);
                    height: auto;
                    aspect-ratio: 760 / 657;
                }

                .github-feedback-head {
                    display: grid;
                    align-items: start;
                    gap: 22px;
                }

                .github-stats {
                    justify-content: flex-start;
                    flex-wrap: wrap;
                }

                .section {
                    padding: 84px 0;
                }
            }

            @media (max-width: 560px) {
                .hero,
                .visual-section,
                .section,
                .cta,
                .footer {
                    width: min(calc(100% - 28px), var(--max));
                }

                .nav {
                    width: 100%;
                    padding: 0 14px;
                }

                .wordmark {
                    width: 118px;
                }

                .nav-actions {
                    gap: 10px;
                }

                .nav-icon-link,
                .lang-toggle,
                .theme-toggle {
                    width: 34px;
                    height: 34px;
                }

                .hero h1 {
                    line-height: 1;
                }

                .hero-wordmark {
                    width: min(82vw, 320px);
                }

                .hero-subtitle {
                    max-width: 330px;
                    margin-top: 18px;
                    font-size: 22px;
                    line-height: 1.28;
                }

                .hero-actions {
                    width: 100%;
                    gap: 10px;
                    margin-top: 22px;
                }

                .hero-actions .button {
                    width: min(100%, 280px);
                }

                .visual-section {
                    min-height: auto;
                    padding: 36px 0 54px;
                }

                .visual-shell {
                    min-height: auto;
                    display: block;
                    padding: 24px 0;
                }

                .visual-stage {
                    height: auto;
                    min-height: auto;
                    display: grid;
                    place-items: center;
                    overflow: visible;
                }

                .component-frame {
                    width: min(100%, 360px);
                    height: auto;
                    aspect-ratio: 760 / 657;
                    max-height: min(58vh, 420px);
                    min-height: 0;
                    max-width: 360px;
                }

                .section {
                    padding: 62px 0;
                }

                .section-title {
                    margin-bottom: 28px;
                    font-size: 34px;
                    line-height: 1.15;
                }

                .feature-stack {
                    gap: 34px;
                }

                .feature-block-shell {
                    display: grid;
                    gap: 0;
                    border-radius: 20px;
                }

                .feature-copy {
                    gap: 16px;
                    padding: 22px;
                }

                .feature-copy h3 {
                    font-size: 26px;
                    line-height: 1.22;
                }

                .feature-media {
                    min-height: 356px;
                    padding: 18px 0 24px;
                    overflow: hidden;
                }

                .feature-block:not(.reverse) .feature-copy,
                .feature-block.reverse .feature-copy {
                    border-radius: 20px 20px 0 0;
                }

                .feature-block:not(.reverse) .feature-media,
                .feature-block.reverse .feature-media {
                    border-radius: 0 0 20px 20px;
                }

                .feature-component-card,
                .feature-work-card,
                .feature-reminder-card {
                    width: min(100%, 334px);
                    height: auto;
                    aspect-ratio: 760 / 657;
                    max-width: 100%;
                }

                .scenario-grid {
                    gap: 12px;
                }

                .scenario-card {
                    min-height: auto;
                    padding: 22px;
                    border-radius: 20px;
                }

                .github-feedback-head {
                    margin-bottom: 28px;
                }

                .github-stats {
                    display: grid;
                    grid-template-columns: repeat(3, minmax(0, 1fr));
                    width: 100%;
                    gap: 8px;
                }

                .github-stat {
                    min-width: 0;
                    padding: 10px;
                }

                .github-stat strong {
                    font-size: 19px;
                }

                .review-card {
                    min-height: auto;
                    border-radius: 16px;
                }

                .review-card p {
                    font-size: 16px;
                    line-height: 1.62;
                }

                .cta {
                    margin-bottom: 42px;
                    padding: 32px 20px;
                    border-radius: 20px;
                }

                .footer-links {
                    flex-wrap: wrap;
                    gap: 10px 18px;
                }

                .feature-copy p,
                .scenario-card p,
                .quote p,
                .cta p {
                    font-size: 17px;
                }
            }
        </style>
    </head>
    <body data-waitlist-endpoint={WAITLIST_ENDPOINT}>
        <header class="nav" aria-label="主导航">
            <a class="logo-link" href="#top" aria-label="TouchAI 首页">
                <img class="wordmark" src="/touchai-wordmark.svg" alt="TouchAI" />
            </a>
            <div class="nav-actions">
                <a
                    class="nav-icon-link"
                    href={repoUrl}
                    target="_blank"
                    rel="noreferrer"
                    aria-label="GitHub"
                    title="GitHub"
                >
                    <svg
                        viewBox="0 0 24 24"
                        aria-hidden="true"
                        fill="none"
                        stroke="currentColor"
                        stroke-linecap="round"
                        stroke-linejoin="round"
                    >
                        <path
                            d="M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.4 5.4 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4"
                        >
                        </path>
                        <path d="M9 18c-4.51 2-5-2-7-2"></path>
                    </svg>
                </a>
                <button
                    class="lang-toggle"
                    type="button"
                    aria-label="Switch language"
                    aria-pressed="false"
                >
                    <svg
                        viewBox="0 0 24 24"
                        aria-hidden="true"
                        fill="none"
                        stroke="currentColor"
                        stroke-linecap="round"
                        stroke-linejoin="round"
                    >
                        <circle cx="12" cy="12" r="10"></circle>
                        <path d="M2 12h20"></path>
                        <path d="M12 2a15.3 15.3 0 0 1 0 20"></path>
                        <path d="M12 2a15.3 15.3 0 0 0 0 20"></path>
                    </svg>
                    <span>中</span>
                </button>
                <button
                    class="theme-toggle"
                    type="button"
                    aria-label="切换黑夜模式"
                    aria-pressed="false"
                    title="切换黑夜模式"
                >
                    <svg
                        class="moon-icon"
                        viewBox="0 0 24 24"
                        aria-hidden="true"
                        fill="none"
                        stroke="currentColor"
                        stroke-linecap="round"
                        stroke-linejoin="round"
                    >
                        <path d="M12 3a6.6 6.6 0 0 0 8.9 8.9A9 9 0 1 1 12 3Z"></path>
                    </svg>
                    <svg
                        class="sun-icon"
                        viewBox="0 0 24 24"
                        aria-hidden="true"
                        fill="none"
                        stroke="currentColor"
                        stroke-linecap="round"
                        stroke-linejoin="round"
                    >
                        <circle cx="12" cy="12" r="4"></circle>
                        <path d="M12 2v2"></path>
                        <path d="M12 20v2"></path>
                        <path d="m4.93 4.93 1.41 1.41"></path>
                        <path d="m17.66 17.66 1.41 1.41"></path>
                        <path d="M2 12h2"></path>
                        <path d="M20 12h2"></path>
                        <path d="m6.34 17.66-1.41 1.41"></path>
                        <path d="m19.07 4.93-1.41 1.41"></path>
                    </svg>
                </button>
            </div>
        </header>

        <main id="top">
            <section class="hero">
                <h1>
                    <img class="hero-wordmark" src="/touch-ai-hero-light.svg?v=3" alt="TouchAI" />
                </h1>
                <p class="hero-subtitle" data-i18n="hero.subtitle">一触即达的桌面效率 Agent</p>
                <div class="hero-actions">
                    <a
                        class="button"
                        href={releasesUrl}
                        target="_blank"
                        rel="noreferrer"
                        data-i18n="hero.download"
                    >
                        下载 TouchAI
                    </a>
                    <a class="button secondary" href={docsUrl} data-i18n="hero.docs" hidden>
                        使用文档
                    </a>
                </div>
            </section>

            <section class="visual-section" aria-label="TouchAI 产品界面">
                <div class="visual-shell">
                    <div class="visual-stage">
                        <ComponentDemo
                            className="component-frame"
                            src="/touchai-intro/touchai-components.html?v=7"
                            title="TouchAI 介绍组件演示"
                        />
                    </div>
                </div>
            </section>

            <section class="section" id="features">
                <h2 class="section-title" data-i18n="features.title">自然融入你的工作流</h2>
                <div class="feature-stack">
                    <article class="feature-block">
                        <div class="feature-block-shell">
                            <div class="feature-copy">
                                <h3 data-i18n="features.one.title">把题目交给桌面 AI</h3>
                                <p data-i18n="features.one.copy">
                                    截图、公式和上下文可以一起进入对话。TouchAI
                                    会理解题面，逐步展开推导，并把关键结论整理成可继续使用的答案。
                                </p>
                            </div>
                            <div class="feature-media solver-media">
                                <div class="phone-card feature-component-card">
                                    <ComponentDemo
                                        className="feature-component-frame"
                                        src="/feature-solver/touchai-components.html?v=17"
                                        title="TouchAI 解题组件演示"
                                    />
                                </div>
                            </div>
                        </div>
                    </article>

                    <article class="feature-block reverse work-feature">
                        <div class="feature-block-shell">
                            <div class="feature-media dark work-media">
                                <div class="feature-work-card">
                                    <ComponentDemo
                                        className="feature-work-frame"
                                        src="/feature-work-organizer/touchai-components.html?v=13"
                                        title="TouchAI 工作整理组件演示"
                                    />
                                </div>
                            </div>
                            <div class="feature-copy">
                                <h3 data-i18n="features.two.title">整理你的复杂工作</h3>
                                <p data-i18n="features.two.copy">
                                    随时把你混乱的任务丢给TouchAI，让他帮你整理归档，专注更有价值的创造
                                </p>
                            </div>
                        </div>
                    </article>

                    <article class="feature-block">
                        <div class="feature-block-shell">
                            <div class="feature-copy">
                                <h3 data-i18n="features.three.title">让世界近在咫尺</h3>
                                <p data-i18n="features.three.copy">
                                    随时呼起，一句自然语言，迅速调用外部工具，无负担无打扰
                                </p>
                            </div>
                            <div class="feature-media reminder-media">
                                <div class="feature-reminder-card">
                                    <ComponentDemo
                                        className="feature-reminder-frame"
                                        src="/feature-reminder/touchai-components.html?v=5"
                                        title="TouchAI MCP 工具调用组件演示"
                                    />
                                </div>
                            </div>
                        </div>
                    </article>
                </div>
            </section>

            <section class="section" id="workflow">
                <h2 class="section-title" data-i18n="workflow.title">丰富的功能特性</h2>
                <div class="scenario-grid">
                    <article class="scenario-card">
                        <h3 data-i18n="workflow.one.title">支持BYOK</h3>
                        <p data-i18n="workflow.one.copy">
                            无厂商锁定，接入你自己的模型，用任意模型驱动TouchAI。
                        </p>
                    </article>
                    <article class="scenario-card">
                        <h3 data-i18n="workflow.two.title">桌面上下文理解</h3>
                        <p data-i18n="workflow.two.copy">
                            围绕当前窗口、剪贴板、文件理解你的桌面上下文，让连续任务自然接上下一步。
                        </p>
                    </article>
                    <article class="scenario-card">
                        <h3 data-i18n="workflow.three.title">桌面操控与执行</h3>
                        <p data-i18n="workflow.three.copy">
                            直接操控电脑、打开应用、查询信息、整理文件并执行桌面动作，让AI帮你操作。
                        </p>
                    </article>
                </div>
            </section>

            <section class="section" id="teams">
                <div class="github-feedback-head">
                    <h2 class="section-title" data-i18n="teams.title">用户反馈</h2>
                    <div class="github-stats" aria-label="GitHub project stats">
                        <div class="github-stat">
                            <strong data-github-stat="stars" aria-live="polite">23</strong>
                            <span data-i18n="teams.stats.stars">Stars</span>
                        </div>
                        <div class="github-stat">
                            <strong data-github-stat="forks" aria-live="polite">22</strong>
                            <span data-i18n="teams.stats.forks">Forks</span>
                        </div>
                        <div class="github-stat">
                            <strong data-github-stat="issues" aria-live="polite">82</strong>
                            <span data-i18n="teams.stats.issues">Open issues</span>
                        </div>
                    </div>
                </div>
                <div class="quote-row review-grid">
                    <article class="review-card">
                        <div class="review-card-content">
                            <div class="review-card-top">
                                <a
                                    class="review-avatar-link"
                                    href="https://github.com/sakukae"
                                    target="_blank"
                                    rel="noreferrer"
                                    aria-label="Open sakukae GitHub profile"
                                >
                                    <img
                                        class="review-avatar"
                                        src="/review-avatars/sakukae.png"
                                        alt=""
                                        loading="lazy"
                                    />
                                </a>
                                <div class="review-title-block">
                                    <div class="review-title-row">
                                        <a
                                            class="review-author-link"
                                            href="https://github.com/sakukae"
                                            target="_blank"
                                            rel="noreferrer"
                                        >
                                            <strong>sakukae</strong>
                                        </a>
                                        <span class="review-platform">GitHub</span>
                                    </div>
                                    <a
                                        class="review-author-link review-handle"
                                        href="https://github.com/sakukae"
                                        target="_blank"
                                        rel="noreferrer"
                                    >
                                        @sakukae
                                    </a>
                                </div>
                            </div>
                            <div class="review-divider" aria-hidden="true"></div>
                            <p data-i18n="teams.review.alpha">
                                “在阅读技术文档的时候，使用 TouchAI
                                一键帮我生成可视化学习架构，帮助我快速理解技术难点，对我来说是一个高效办公的好工具。”
                            </p>
                        </div>
                    </article>
                    <article class="review-card">
                        <div class="review-card-content">
                            <div class="review-card-top">
                                <a
                                    class="review-avatar-link"
                                    href="https://github.com/ARCJ137442"
                                    target="_blank"
                                    rel="noreferrer"
                                    aria-label="Open ARCJ137442 GitHub profile"
                                >
                                    <img
                                        class="review-avatar"
                                        src="/review-avatars/arcj137442.png"
                                        alt=""
                                        loading="lazy"
                                    />
                                </a>
                                <div class="review-title-block">
                                    <div class="review-title-row">
                                        <a
                                            class="review-author-link"
                                            href="https://github.com/ARCJ137442"
                                            target="_blank"
                                            rel="noreferrer"
                                        >
                                            <strong>ARCJ137442</strong>
                                        </a>
                                        <span class="review-platform">GitHub</span>
                                    </div>
                                    <a
                                        class="review-author-link review-handle"
                                        href="https://github.com/ARCJ137442"
                                        target="_blank"
                                        rel="noreferrer"
                                    >
                                        @ARCJ137442
                                    </a>
                                </div>
                            </div>
                            <div class="review-divider" aria-hidden="true"></div>
                            <p data-i18n="teams.review.beta">
                                “平时忽然有什么问题，不管是日常生活还是问个技术，几下子唤醒敲字就能开问，能搜索能读文档能画图，随呼随走也能钉着放一边，可谓无处不在，一触即达。”
                            </p>
                        </div>
                    </article>
                    <article class="review-card">
                        <div class="review-card-content">
                            <div class="review-card-top">
                                <a
                                    class="review-avatar-link"
                                    href="https://github.com/TheEverests"
                                    target="_blank"
                                    rel="noreferrer"
                                    aria-label="Open TheEverests GitHub profile"
                                >
                                    <img
                                        class="review-avatar"
                                        src="/review-avatars/theeverests.png"
                                        alt=""
                                        loading="lazy"
                                    />
                                </a>
                                <div class="review-title-block">
                                    <div class="review-title-row">
                                        <a
                                            class="review-author-link"
                                            href="https://github.com/TheEverests"
                                            target="_blank"
                                            rel="noreferrer"
                                        >
                                            <strong>TheEverests</strong>
                                        </a>
                                        <span class="review-platform">GitHub</span>
                                    </div>
                                    <a
                                        class="review-author-link review-handle"
                                        href="https://github.com/TheEverests"
                                        target="_blank"
                                        rel="noreferrer"
                                    >
                                        @TheEverests
                                    </a>
                                </div>
                            </div>
                            <div class="review-divider" aria-hidden="true"></div>
                            <p data-i18n="teams.review.gamma">
                                “在解答疑难题目时，调用 TouchAI
                                进行智能解析；其不仅在分析答案的同时，能够绘制多种图形辅助理解，从而使抽象概念得以直观呈现，实现学习支持的高效可及与即时响应。”
                            </p>
                        </div>
                    </article>
                    <article class="review-card">
                        <div class="review-card-content">
                            <div class="review-card-top">
                                <span
                                    class="review-avatar-link"
                                    aria-label="Anonymous GitHub avatar"
                                >
                                    <img
                                        class="review-avatar"
                                        src="/review-avatars/anonymous.png"
                                        alt=""
                                        loading="lazy"
                                    />
                                </span>
                                <div class="review-title-block">
                                    <div class="review-title-row">
                                        <strong>匿名</strong>
                                        <span class="review-platform">GitHub</span>
                                    </div>
                                    <span class="review-handle">@anonymous</span>
                                </div>
                            </div>
                            <div class="review-divider" aria-hidden="true"></div>
                            <p data-i18n="teams.review.delta">
                                “之前用过好多 agent
                                工具，其中很大的问题就是要自己培养，太费精力，到头来成了一个玩具。但是用过这款下来，真的能解决我的需求。”
                            </p>
                        </div>
                    </article>
                </div>
            </section>

            <section class="cta" id="download">
                <h2 data-i18n="cta.title">开始使用 TouchAI</h2>
                <p data-i18n="cta.copy">体验近在咫尺的AI陪伴</p>
                <a
                    class="button secondary"
                    href={releasesUrl}
                    target="_blank"
                    rel="noreferrer"
                    data-i18n="cta.download"
                >
                    下载 TouchAI
                </a>
            </section>
        </main>

        <footer class="footer">
            <div class="footer-links">
                <a
                    href="https://touch-ai.org/"
                    target="_blank"
                    rel="noreferrer"
                    data-i18n="footer.official"
                >
                    官网
                </a>
                <a href={repoUrl} target="_blank" rel="noreferrer">GitHub</a>
                <a href={docsUrl} target="_blank" rel="noreferrer" data-i18n="footer.docs" hidden>
                    文档
                </a>
                <a
                    href="https://github.com/TouchAI-org/TouchAI/issues"
                    target="_blank"
                    rel="noreferrer"
                    data-i18n="footer.contact"
                >
                    联系我们
                </a>
            </div>
            <div data-i18n="footer.copyright">© 2026 TouchAI. GPL-3.0-or-later.</div>
        </footer>

        <script>
            import { gsap } from 'gsap';
            import ScrollTrigger from 'gsap/ScrollTrigger';
            import { createShader, playSweep } from 'glimm';
            import { ensureTouchaiLightDemoRuntime } from '../scripts/component-demo-runtime';

            (async () => {
                document.body.dataset.pageScript = 'started';
                window.__touchaiBootState = {
                    stage: 'started',
                };
                let touchaiDemoRuntime = null;
                const sendToDemo = (target, data) =>
                    touchaiDemoRuntime?.send(target, data) ?? false;

                try {
                    document.body.dataset.componentRuntime = 'initializing';
                    window.__touchaiBootState.stage = 'runtime-initializing';
                    touchaiDemoRuntime = ensureTouchaiLightDemoRuntime();
                    document.body.dataset.componentRuntimeFactory =
                        document.body.dataset.touchaiRuntimeFactory || 'unknown';
                    document.body.dataset.componentRuntime = 'ready';
                    window.__touchaiBootState.stage = 'runtime-ready';
                    touchaiDemoRuntime.mountAll();
                    document.body.dataset.componentRuntime = 'ready';
                    document.body.dataset.componentMountAll = 'done';
                    window.__touchaiBootState.stage = 'mount-all-done';
                } catch (error) {
                    document.body.dataset.componentMountAll = 'failed';
                    window.__touchaiBootState.stage = 'mount-all-failed';
                    window.__touchaiBootState.error =
                        error instanceof Error ? error.message : String(error);
                    throw error;
                }

                window.gsap = gsap;
                window.ScrollTrigger = ScrollTrigger;
                gsap.registerPlugin(ScrollTrigger);
                document.body.dataset.pageScript = 'bootstrapped';
                window.__touchaiBootState.stage = 'bootstrapped';

                const translations = {
                    zh: {
                        'nav.features': '功能',
                        'nav.workflow': '场景',
                        'nav.teams': '评价',
                        'nav.download': '下载',
                        'hero.subtitle': '一触即达的桌面效率 Agent',
                        'hero.download': '下载 TouchAI',
                        'hero.docs': '使用文档',
                        'features.title': '自然融入你的工作流',
                        'features.one.title': '把题目交给桌面 AI',
                        'features.one.copy':
                            '截图、公式和上下文可以一起进入对话。TouchAI 会理解题面，逐步展开推导，并把关键结论整理成可继续使用的答案。',
                        'features.two.title': '整理你的复杂工作',
                        'features.two.copy':
                            '随时把你混乱的任务丢给TouchAI，让他帮你整理归档，专注更有价值的创造',
                        'features.three.title': '让世界近在咫尺',
                        'features.three.copy':
                            '随时呼起，一句自然语言，迅速调用外部工具，无负担无打扰',
                        'workflow.title': '丰富的功能特性',
                        'workflow.one.title': '支持BYOK',
                        'workflow.one.copy':
                            '无厂商锁定，接入你自己的模型，用任意模型驱动TouchAI。',
                        'workflow.two.title': '桌面上下文理解',
                        'workflow.two.copy':
                            '围绕当前窗口、剪贴板、文件理解你的桌面上下文，让连续任务自然接上下一步。',
                        'workflow.three.title': '桌面操控与执行',
                        'workflow.three.copy':
                            '直接操控电脑、打开应用、查询信息、整理文件并执行桌面动作，让AI帮你操作。',
                        'teams.title': '用户反馈',
                        'teams.stats.stars': 'Stars',
                        'teams.stats.forks': 'Forks',
                        'teams.stats.issues': 'Open issues',
                        'teams.one.quote':
                            '开发者正在 GitHub Issues 里围绕桌面唤起、模型接入和自动化工作流提交反馈，项目保持持续迭代。',
                        'teams.one.label': 'Issues 反馈',
                        'teams.one.link': '查看 Issues',
                        'teams.two.quote':
                            'TouchAI 采用 GPL-3.0 开源协议，当前以 TypeScript 为主要语言，欢迎围绕桌面 Agent 体验提交改进建议。',
                        'teams.two.label': '开源协作',
                        'teams.two.link': '打开仓库',
                        'teams.three.quote':
                            '关注者可以通过 Stars、Forks 和 Discussions 跟进项目方向，也可以直接参与功能讨论与体验反馈。',
                        'teams.three.label': '社区讨论',
                        'teams.three.link': '查看 Discussions',
                        'teams.review.alpha':
                            '“在阅读技术文档的时候，使用 TouchAI 一键帮我生成可视化学习架构，帮助我快速理解技术难点，对我来说是一个高效办公的好工具。”',
                        'teams.review.beta':
                            '“平时忽然有什么问题，不管是日常生活还是问个技术，几下子唤醒敲字就能开问，能搜索能读文档能画图，随呼随走也能钉着放一边，可谓无处不在，一触即达。”',
                        'teams.review.gamma':
                            '“在解答疑难题目时，调用 TouchAI 进行智能解析；其不仅在分析答案的同时，能够绘制多种图形辅助理解，从而使抽象概念得以直观呈现，实现学习支持的高效可及与即时响应。”',
                        'teams.review.delta':
                            '“之前用过好多 agent 工具，其中很大的问题就是要自己培养，太费精力，到头来成了一个玩具。但是用过这款下来，真的能解决我的需求。”',
                        'cta.title': '开始使用 TouchAI',
                        'cta.copy': '体验近在咫尺的AI陪伴',
                        'cta.download': '下载 TouchAI',
                        'footer.official': '官网',
                        'footer.docs': '文档',
                        'footer.contact': '联系我们',
                        'footer.copyright': '© 2026 TouchAI. GPL-3.0-or-later.',
                    },
                    en: {
                        'nav.features': 'Features',
                        'nav.workflow': 'Use cases',
                        'nav.teams': 'Stories',
                        'nav.download': 'Download',
                        'hero.subtitle': 'A desktop productivity agent, one touch away',
                        'hero.download': 'Download TouchAI',
                        'hero.docs': 'Docs',
                        'features.title': 'Naturally fits into your workflow',
                        'features.one.title': 'Hand the problem to desktop AI.',
                        'features.one.copy':
                            'Screenshots, formulas, and context can enter the same conversation. TouchAI understands the prompt, unfolds the derivation step by step, and organizes the final answer for reuse.',
                        'features.two.title': 'Organize your complex work.',
                        'features.two.copy':
                            'Drop messy tasks into TouchAI anytime. It helps organize and archive them so you can focus on more valuable creation.',
                        'features.three.title': 'Keep the world within reach.',
                        'features.three.copy':
                            'Call it up anytime. One natural-language sentence quickly invokes external tools with no burden and no interruption.',
                        'workflow.title': 'Rich feature set',
                        'workflow.one.title': 'BYOK supported',
                        'workflow.one.copy':
                            'No vendor lock-in. Connect your own models and drive TouchAI with any model you choose.',
                        'workflow.two.title': 'Desktop context awareness',
                        'workflow.two.copy':
                            'Understand the current window, clipboard, files, and recent actions so ongoing work can continue without repeated setup.',
                        'workflow.three.title': 'Desktop control and execution',
                        'workflow.three.copy':
                            'Operate the computer, open apps, look things up, organize files, and carry actions through beyond the conversation itself.',
                        'teams.title': 'User feedback',
                        'teams.stats.stars': 'Stars',
                        'teams.stats.forks': 'Forks',
                        'teams.stats.issues': 'Open issues',
                        'teams.one.quote':
                            'Developers are using GitHub Issues to discuss desktop summon, model access, and automation workflows while the project keeps moving.',
                        'teams.one.label': 'Issue feedback',
                        'teams.one.link': 'View Issues',
                        'teams.two.quote':
                            'TouchAI is GPL-3.0 licensed and primarily written in TypeScript. Suggestions around the desktop Agent experience are welcome.',
                        'teams.two.label': 'Open-source work',
                        'teams.two.link': 'Open repository',
                        'teams.three.quote':
                            'Followers can track direction through Stars, Forks, and Discussions, or join feature conversations directly.',
                        'teams.three.label': 'Community discussion',
                        'teams.three.link': 'View Discussions',
                        'teams.review.alpha':
                            '“When reading technical documentation, TouchAI can generate a visual learning structure for me with one prompt, helping me grasp difficult concepts much faster. It is a genuinely efficient productivity tool.”',
                        'teams.review.beta':
                            '“Whenever a question comes up, whether it is daily life or something technical, I can wake it up and start asking in seconds. It can search, read docs, draw diagrams, stay pinned, or leave just as quickly. It really feels everywhere, one touch away.”',
                        'teams.review.gamma':
                            '“When solving difficult problems, TouchAI provides intelligent analysis and can also draw multiple supporting diagrams, making abstract concepts more intuitive and turning learning support into something immediate and accessible.”',
                        'teams.review.delta':
                            '“I used many agent tools before, and the biggest problem was that they needed too much training and energy, so they ended up feeling like toys. This one actually solves my real needs.”',
                        'cta.title': 'Get started with TouchAI',
                        'cta.copy': 'Experience AI companionship within reach.',
                        'cta.download': 'Download TouchAI',
                        'footer.official': 'Official site',
                        'footer.docs': 'Docs',
                        'footer.contact': 'Contact us',
                        'footer.copyright': '© 2026 TouchAI. GPL-3.0-or-later.',
                    },
                };

                const featureProgressByFrame = new WeakMap();
                function syncFeatureDemoProgress(frame, progress) {
                    if (!frame) return;
                    featureProgressByFrame.set(frame, progress);
                    sendToDemo(frame, {
                        type: 'touchai-set-scroll-progress',
                        progress,
                    });
                }

                function restoreFeatureDemoProgress(frame) {
                    if (!frame) return;
                    const progress = featureProgressByFrame.get(frame) ?? 0;
                    syncFeatureDemoProgress(frame, progress);
                    window.setTimeout(() => syncFeatureDemoProgress(frame, progress), 120);
                    window.setTimeout(() => syncFeatureDemoProgress(frame, progress), 360);
                }

                const setLanguage = (language) => {
                    const lang = language === 'en' ? 'en' : 'zh';
                    document.documentElement.lang = lang === 'en' ? 'en' : 'zh-CN';
                    document.querySelectorAll('[data-i18n]').forEach((node) => {
                        const key = node.dataset.i18n;
                        if (key && translations[lang][key]) {
                            node.textContent = translations[lang][key];
                        }
                    });
                    const toggle = document.querySelector('.lang-toggle');
                    if (toggle) {
                        toggle.setAttribute('aria-pressed', String(lang === 'en'));
                        toggle.setAttribute(
                            'aria-label',
                            lang === 'en' ? '切换到中文' : 'Switch to English'
                        );
                        toggle.setAttribute(
                            'title',
                            lang === 'en' ? '切换到中文' : 'Switch to English'
                        );
                        toggle.querySelector('span').textContent = lang === 'en' ? 'EN' : '中';
                    }
                    const introDemo = document.querySelector('.component-frame');
                    if (introDemo) {
                        const nextSrc =
                            lang === 'en'
                                ? '/touchai-intro-en/touchai-components.html?v=1'
                                : '/touchai-intro/touchai-components.html?v=8';
                        if (introDemo.dataset.src !== nextSrc) {
                            introDemo.dataset.src = nextSrc;
                            introDemo.dataset.title =
                                lang === 'en'
                                    ? 'TouchAI intro component demo'
                                    : 'TouchAI 介绍组件演示';
                            Promise.resolve(introDemo.reload?.()).then(() => {
                                syncComponentBackground();
                            });
                        }
                    }
                    const solverDemo = document.querySelector('.feature-component-frame');
                    if (solverDemo) {
                        const nextSolverSrc =
                            lang === 'en'
                                ? '/feature-solver-en/touchai-components.html?v=1'
                                : '/feature-solver/touchai-components.html?v=17';
                        if (solverDemo.dataset.src !== nextSolverSrc) {
                            solverDemo.dataset.src = nextSolverSrc;
                            solverDemo.dataset.title =
                                lang === 'en'
                                    ? 'TouchAI math solver component demo'
                                    : 'TouchAI 解题组件演示';
                            Promise.resolve(solverDemo.reload?.()).then(() => {
                                syncComponentBackground();
                                restoreFeatureDemoProgress(solverDemo);
                            });
                        }
                    }
                    const workDemo = document.querySelector('.feature-work-frame');
                    if (workDemo) {
                        const nextWorkSrc =
                            lang === 'en'
                                ? '/feature-work-organizer-en/touchai-components.html?v=1'
                                : '/feature-work-organizer/touchai-components.html?v=13';
                        if (workDemo.dataset.src !== nextWorkSrc) {
                            workDemo.dataset.src = nextWorkSrc;
                            workDemo.dataset.title =
                                lang === 'en'
                                    ? 'TouchAI work organizer component demo'
                                    : 'TouchAI 工作整理组件演示';
                            Promise.resolve(workDemo.reload?.()).then(() => {
                                syncComponentBackground();
                                restoreFeatureDemoProgress(workDemo);
                            });
                        }
                    }
                    const reminderDemo = document.querySelector('.feature-reminder-frame');
                    if (reminderDemo) {
                        const nextReminderSrc =
                            lang === 'en'
                                ? '/feature-reminder-en/touchai-components.html?v=1'
                                : '/feature-reminder/touchai-components.html?v=5';
                        if (reminderDemo.dataset.src !== nextReminderSrc) {
                            reminderDemo.dataset.src = nextReminderSrc;
                            reminderDemo.dataset.title =
                                lang === 'en'
                                    ? 'TouchAI meeting reminder component demo'
                                    : 'TouchAI MCP 工具调用组件演示';
                            Promise.resolve(reminderDemo.reload?.()).then(() => {
                                syncComponentBackground();
                                restoreFeatureDemoProgress(reminderDemo);
                            });
                        }
                    }
                    localStorage.setItem('touchai-language', lang);
                };

                const languageToggle = document.querySelector('.lang-toggle');
                const savedLanguage = localStorage.getItem('touchai-language');
                setLanguage(savedLanguage === 'en' ? 'en' : 'zh');

                const componentBackgroundFrames = () =>
                    document.querySelectorAll('touchai-component-demo');

                const syncFeatureFrameSizing = () => {
                    [
                        ['.feature-component-card', '.feature-component-frame'],
                        ['.feature-work-card', '.feature-work-frame'],
                        ['.feature-reminder-card', '.feature-reminder-frame'],
                    ].forEach(([cardSelector, frameSelector]) => {
                        const card = document.querySelector(cardSelector);
                        const frame = document.querySelector(frameSelector);
                        if (!frame) return;

                        if (card) {
                            const width = card.getBoundingClientRect().width || 0;
                            if (width > 0) {
                                card.style.height = `${Math.round((width * 657) / 760)}px`;
                                card.style.setProperty('--component-scale', String(width / 760));
                            }
                        }

                        frame.style.height = '657px';
                        frame.style.minHeight = '657px';
                        frame.style.maxHeight = '657px';
                        frame.style.background = 'transparent';
                    });
                };

                const syncComponentBackground = () => {
                    requestAnimationFrame(() => {
                        const componentStageBg = getComputedStyle(document.documentElement)
                            .getPropertyValue('--component-stage-bg')
                            .trim();
                        const featureShellBg = getComputedStyle(document.documentElement)
                            .getPropertyValue('--feature-shell-bg')
                            .trim();
                        componentBackgroundFrames().forEach((frame) => {
                            const isSolverFrame =
                                frame.classList.contains('feature-component-frame');
                            const isFeatureFrame =
                                isSolverFrame ||
                                frame.classList.contains('feature-work-frame') ||
                                frame.classList.contains('feature-reminder-frame');
                            const isIntroFrame = frame.classList.contains('component-frame');
                            const nextBg = isIntroFrame
                                ? 'transparent'
                                : isFeatureFrame
                                  ? featureShellBg
                                  : componentStageBg;
                            frame.style.setProperty('--page-bg', nextBg);
                            if (!isSolverFrame) {
                                frame.style.background = nextBg;
                            }
                            sendToDemo(frame, { type: 'touchai-page-bg', background: nextBg });
                        });
                        syncFeatureFrameSizing();
                    });
                };

                const setTheme = (theme) => {
                    const nextTheme = theme === 'dark' ? 'dark' : 'light';
                    document.documentElement.dataset.theme = nextTheme;
                    document
                        .querySelector('meta[name="theme-color"]')
                        ?.setAttribute('content', nextTheme === 'dark' ? '#101014' : '#ffffff');
                    const themeToggle = document.querySelector('.theme-toggle');
                    if (themeToggle) {
                        themeToggle.setAttribute('aria-pressed', String(nextTheme === 'dark'));
                        themeToggle.setAttribute(
                            'aria-label',
                            nextTheme === 'dark' ? '切换白天模式' : '切换黑夜模式'
                        );
                        themeToggle.setAttribute(
                            'title',
                            nextTheme === 'dark' ? '切换白天模式' : '切换黑夜模式'
                        );
                    }
                    localStorage.setItem('touchai-theme', nextTheme);
                    syncComponentBackground();
                };

                const repoStats = {
                    stars: 23,
                    forks: 22,
                    issues: 82,
                };
                const statNodes = {
                    stars: document.querySelector('[data-github-stat="stars"]'),
                    forks: document.querySelector('[data-github-stat="forks"]'),
                    issues: document.querySelector('[data-github-stat="issues"]'),
                };
                const formatStat = (value) => {
                    const num = Number(value);
                    return Number.isFinite(num) ? new Intl.NumberFormat('en-US').format(num) : null;
                };
                const renderRepoStats = (nextStats) => {
                    if (statNodes.stars && nextStats.stars != null)
                        statNodes.stars.textContent = String(nextStats.stars);
                    if (statNodes.forks && nextStats.forks != null)
                        statNodes.forks.textContent = String(nextStats.forks);
                    if (statNodes.issues && nextStats.issues != null)
                        statNodes.issues.textContent = String(nextStats.issues);
                };
                const refreshRepoStats = async () => {
                    try {
                        const response = await fetch(
                            `https://api.github.com/repos/TouchAI-org/TouchAI?ts=${Date.now()}`,
                            {
                                cache: 'no-store',
                                headers: {
                                    Accept: 'application/vnd.github+json',
                                },
                            }
                        );
                        if (!response.ok) return;
                        const data = await response.json();
                        const nextStats = {
                            stars: formatStat(data.stargazers_count),
                            forks: formatStat(data.forks_count),
                            issues: formatStat(data.open_issues_count),
                        };
                        Object.assign(repoStats, nextStats);
                        renderRepoStats(repoStats);
                    } catch (error) {
                        renderRepoStats(repoStats);
                    }
                };

                const savedTheme = localStorage.getItem('touchai-theme');
                const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
                setTheme(savedTheme || (prefersDark ? 'dark' : 'light'));
                renderRepoStats(repoStats);
                refreshRepoStats();
                window.setInterval(refreshRepoStats, 10 * 60 * 1000);

                componentBackgroundFrames().forEach((frame) => {
                    frame.addEventListener('load', syncComponentBackground);
                    frame.addEventListener('touchai-component-loaded', syncComponentBackground);
                });
                syncFeatureFrameSizing();

                let glimmCanvas = null;
                let glimmController = null;
                let glimmUnavailable = false;

                const ensureGlimmController = () => {
                    if (glimmController || glimmUnavailable) return glimmController;

                    glimmCanvas = document.createElement('canvas');
                    glimmCanvas.className = 'glimm-click-layer';
                    glimmCanvas.setAttribute('aria-hidden', 'true');
                    document.body.appendChild(glimmCanvas);

                    try {
                        glimmController = createShader({
                            canvas: glimmCanvas,
                            palette: 'berry',
                            direction: 'ltr',
                            bandTight: 0.78,
                            brightness:
                                document.documentElement.dataset.theme === 'dark' ? 1.26 : 1.48,
                            waveAmount: 1.34,
                            rippleAmount: 1.24,
                            waveSpeed: 1.16,
                            swellAmount: 1.1,
                        });
                    } catch (error) {
                        glimmUnavailable = true;
                        glimmCanvas.remove();
                        glimmCanvas = null;
                    }

                    return glimmController;
                };

                let activeGlimmSweep = null;
                const playGlimmSweep = (midpointAction, options = {}) => {
                    const controller = ensureGlimmController();
                    if (!controller) {
                        midpointAction?.();
                        return Promise.resolve();
                    }
                    activeGlimmSweep?.cancel?.();
                    document.body.classList.add('is-glimm-transitioning');
                    controller.setBrightness(
                        document.documentElement.dataset.theme === 'dark' ? 1.26 : 1.48
                    );
                    let handle;
                    try {
                        handle = playSweep(controller, {
                            palette: options.palette ?? 'berry',
                            direction: options.direction ?? 'ltr',
                            sweepMs: options.sweepMs ?? 1320,
                            outroMs: options.outroMs ?? 860,
                            bandTight: options.bandTight ?? 0.78,
                            peakAlpha: options.peakAlpha ?? 1.16,
                            brightness:
                                options.brightness ??
                                (document.documentElement.dataset.theme === 'dark' ? 1.26 : 1.48),
                            waveAmount: options.waveAmount ?? 1.34,
                            rippleAmount: options.rippleAmount ?? 1.24,
                            waveSpeed: options.waveSpeed ?? 1.16,
                            swellAmount: options.swellAmount ?? 1.1,
                            onMidpoint: async () => {
                                await midpointAction?.();
                            },
                            onComplete: () => {
                                document.body.classList.remove('is-glimm-transitioning');
                                activeGlimmSweep = null;
                            },
                        });
                    } catch (error) {
                        glimmUnavailable = true;
                        glimmCanvas?.remove();
                        glimmCanvas = null;
                        glimmController = null;
                        return Promise.resolve(midpointAction?.()).finally(() => {
                            document.body.classList.remove('is-glimm-transitioning');
                            activeGlimmSweep = null;
                        });
                    }
                    activeGlimmSweep = handle;
                    return handle.done.finally(() => {
                        document.body.classList.remove('is-glimm-transitioning');
                    });
                };

                document.querySelectorAll('a, button').forEach((target) => {
                    target.classList.add('interactive-click');
                    target.addEventListener('pointerdown', () => {
                        target.classList.add('is-pressing');
                    });
                    ['pointerup', 'pointerleave', 'pointercancel', 'blur'].forEach((eventName) => {
                        target.addEventListener(eventName, () =>
                            target.classList.remove('is-pressing')
                        );
                    });
                });

                document.querySelectorAll('.theme-toggle, .lang-toggle').forEach((target) => {
                    target.addEventListener(
                        'click',
                        (event) => {
                            event.stopImmediatePropagation();
                            event.preventDefault();
                            target.classList.remove('is-pressing');
                            playGlimmSweep(() => {
                                if (target.classList.contains('theme-toggle')) {
                                    setTheme(
                                        document.documentElement.dataset.theme === 'dark'
                                            ? 'light'
                                            : 'dark'
                                    );
                                    return;
                                }
                                const nextLanguage =
                                    document.documentElement.lang === 'en' ? 'zh' : 'en';
                                setLanguage(nextLanguage);
                            });
                        },
                        true
                    );
                });

                const solverFrame = document.querySelector('.feature-component-frame');
                const solverCard = document.querySelector('.feature-component-card');
                if (solverFrame) {
                    syncFeatureDemoProgress(solverFrame, 0);
                    solverFrame.addEventListener('load', () => {
                        syncFeatureDemoProgress(
                            solverFrame,
                            featureProgressByFrame.get(solverFrame) ?? 0
                        );
                    });
                    window.addEventListener('message', (event) => {
                        if (event.data?.type === 'touchai-solver-ready') {
                            syncFeatureDemoProgress(
                                solverFrame,
                                featureProgressByFrame.get(solverFrame) ?? 0
                            );
                        }
                    });
                }

                const workOrganizerFrame = document.querySelector('.feature-work-frame');
                const workOrganizerCard = document.querySelector('.feature-work-card');
                if (workOrganizerFrame) {
                    syncFeatureDemoProgress(workOrganizerFrame, 0);
                    workOrganizerFrame.addEventListener('load', () => {
                        syncFeatureDemoProgress(
                            workOrganizerFrame,
                            featureProgressByFrame.get(workOrganizerFrame) ?? 0
                        );
                    });
                    window.addEventListener('message', (event) => {
                        if (event.data?.type === 'touchai-work-organizer-ready') {
                            syncFeatureDemoProgress(
                                workOrganizerFrame,
                                featureProgressByFrame.get(workOrganizerFrame) ?? 0
                            );
                        }
                    });
                }

                const reminderFrame = document.querySelector('.feature-reminder-frame');
                const reminderCard = document.querySelector('.feature-reminder-card');
                if (reminderFrame) {
                    syncFeatureDemoProgress(reminderFrame, 0);
                    reminderFrame.addEventListener('load', () => {
                        syncFeatureDemoProgress(
                            reminderFrame,
                            featureProgressByFrame.get(reminderFrame) ?? 0
                        );
                    });
                    window.addEventListener('message', (event) => {
                        if (event.data?.type === 'touchai-reminder-ready') {
                            syncFeatureDemoProgress(
                                reminderFrame,
                                featureProgressByFrame.get(reminderFrame) ?? 0
                            );
                        }
                    });
                }

                const replayEmbeddedComponent = async (frame) => {
                    const progress = featureProgressByFrame.get(frame) ?? 0;
                    await Promise.resolve(frame.reload?.());
                    syncFeatureDemoProgress(frame, progress);
                    window.setTimeout(() => syncFeatureDemoProgress(frame, progress), 120);
                    window.setTimeout(() => syncFeatureDemoProgress(frame, progress), 360);
                };

                const bindReplayCard = (card, frame, label) => {
                    if (!card || !frame) return;
                    let replaying = false;
                    card.setAttribute('role', 'button');
                    card.setAttribute('tabindex', '0');
                    card.setAttribute('aria-label', `${label}，点击刷新当前滚动进度`);

                    const replay = async () => {
                        if (replaying) return;
                        replaying = true;
                        try {
                            await replayEmbeddedComponent(frame);
                        } finally {
                            window.setTimeout(() => {
                                replaying = false;
                            }, 900);
                        }
                    };

                    card.addEventListener('click', () => {
                        replay();
                    });
                    card.addEventListener('keydown', (event) => {
                        if (event.key !== 'Enter' && event.key !== ' ') return;
                        event.preventDefault();
                        replay();
                    });
                };

                bindReplayCard(solverCard, solverFrame, '解题对话框');
                bindReplayCard(workOrganizerCard, workOrganizerFrame, '工作整理对话框');
                bindReplayCard(reminderCard, reminderFrame, '提醒对话框');

                const reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;

                gsap.utils.toArray('.hero, .section, .cta').forEach((section, index) => {
                    if (reduceMotion) {
                        gsap.set(section, { autoAlpha: 1, y: 0 });
                        return;
                    }

                    gsap.from(section, {
                        autoAlpha: 0,
                        y: 24,
                        duration: 0.8,
                        ease: 'power2.out',
                        scrollTrigger: {
                            trigger: section,
                            start: 'top 82%',
                            toggleActions: 'play none none reverse',
                        },
                    });
                });

                if (!reduceMotion) {
                    const workflowSection = document.querySelector('#workflow');
                    const scenarioCards = workflowSection
                        ? gsap.utils.toArray('#workflow .scenario-card')
                        : [];
                    const featureFrames = [solverFrame, workOrganizerFrame, reminderFrame].filter(
                        Boolean
                    );
                    const visualSection = document.querySelector('.visual-section');
                    const visualShell = document.querySelector('.visual-shell');
                    const introDemo = document.querySelector('.component-frame');

                    const setupWorkflowPointerEffects = () => {
                        if (!workflowSection || !scenarioCards.length) return () => {};

                        const cleanups = scenarioCards.map((card) => {
                            const handlePointerMove = (event) => {
                                const rect = card.getBoundingClientRect();
                                const x = (event.clientX - rect.left) / rect.width;
                                const y = (event.clientY - rect.top) / rect.height;

                                gsap.to(card, {
                                    rotationY: gsap.utils.mapRange(0, 1, -7, 7, x),
                                    rotationX: gsap.utils.mapRange(0, 1, 7, -7, y),
                                    scale: 1.018,
                                    '--scenario-glow-x': `${x * 100}%`,
                                    '--scenario-glow-y': `${y * 100}%`,
                                    '--scenario-glow-opacity': 1,
                                    duration: 0.35,
                                    ease: 'power2.out',
                                    overwrite: 'auto',
                                });
                            };

                            const handlePointerEnter = () => {
                                gsap.fromTo(
                                    card,
                                    { '--scenario-glow-opacity': 0.2 },
                                    {
                                        '--scenario-glow-opacity': 1,
                                        duration: 0.25,
                                        ease: 'power2.out',
                                    }
                                );
                                gsap.fromTo(
                                    card,
                                    {
                                        '--scenario-shine-x': '-120%',
                                        '--scenario-shine-opacity': 0,
                                    },
                                    {
                                        '--scenario-shine-x': '120%',
                                        '--scenario-shine-opacity': 0.68,
                                        duration: 0.82,
                                        ease: 'power2.out',
                                        overwrite: 'auto',
                                        onComplete: () => {
                                            gsap.set(card, { '--scenario-shine-opacity': 0 });
                                        },
                                    }
                                );
                            };

                            const handlePointerLeave = () => {
                                gsap.to(card, {
                                    rotationX: 0,
                                    rotationY: 0,
                                    scale: 1,
                                    '--scenario-glow-opacity': 0,
                                    duration: 0.55,
                                    ease: 'power3.out',
                                    overwrite: 'auto',
                                });
                            };

                            card.addEventListener('pointermove', handlePointerMove);
                            card.addEventListener('pointerenter', handlePointerEnter);
                            card.addEventListener('pointerleave', handlePointerLeave);

                            return () => {
                                card.removeEventListener('pointermove', handlePointerMove);
                                card.removeEventListener('pointerenter', handlePointerEnter);
                                card.removeEventListener('pointerleave', handlePointerLeave);
                                gsap.set(card, {
                                    rotationX: 0,
                                    rotationY: 0,
                                    scale: 1,
                                    '--scenario-glow-opacity': 0,
                                    '--scenario-shine-opacity': 0,
                                });
                            };
                        });

                        return () => {
                            cleanups.forEach((cleanup) => cleanup());
                        };
                    };

                    const setupIntroScrollTrigger = (compact) => {
                        if (!visualSection || !visualShell || !introDemo) return () => {};

                        let isActive = true;
                        let componentTrigger;
                        const syncComponent = (progress) => {
                            sendToDemo(introDemo, { type: 'touchai-set-progress', progress });
                        };
                        const refreshPinnedIntro = () => {
                            ScrollTrigger.refresh();
                            syncComponent(componentTrigger?.progress ?? 0);
                        };

                        const handleIntroReady = () => {
                            if (!isActive) return;
                            requestAnimationFrame(() => {
                                if (isActive) refreshPinnedIntro();
                            });
                        };
                        const handleReadyMessage = (event) => {
                            if (!isActive || event.data?.type !== 'touchai-component-ready') return;
                            requestAnimationFrame(() => {
                                if (isActive) refreshPinnedIntro();
                            });
                        };

                        gsap.set(visualShell, {
                            scale: compact ? 1 : 0.985,
                            transformOrigin: 'center center',
                        });

                        const timeline = gsap
                            .timeline({
                                scrollTrigger: {
                                    trigger: visualSection,
                                    start: compact ? 'top 82%' : 'top top',
                                    end: compact
                                        ? 'bottom 18%'
                                        : () => `+=${Math.max(window.innerHeight * 3.45, 2800)}`,
                                    pin: !compact,
                                    pinSpacing: true,
                                    anticipatePin: 1,
                                    scrub: compact ? true : 0.55,
                                    invalidateOnRefresh: true,
                                    onRefresh: (self) => {
                                        componentTrigger = self;
                                        gsap.set(visualShell, {
                                            scale: compact ? 1 : 0.985,
                                        });
                                        syncComponent(self.progress);
                                    },
                                    onEnter: () => syncComponent(componentTrigger?.progress ?? 0),
                                    onEnterBack: () =>
                                        syncComponent(componentTrigger?.progress ?? 1),
                                    onUpdate: (self) => {
                                        componentTrigger = self;
                                        syncComponent(self.progress);
                                    },
                                    onLeave: () => syncComponent(1),
                                    onLeaveBack: () => syncComponent(0),
                                },
                            })
                            .fromTo(
                                visualShell,
                                { scale: 0.965, y: 0, opacity: 0.65 },
                                { scale: 1, y: 0, opacity: 1, duration: 0.35, ease: 'power2.out' }
                            )
                            .to(introDemo, { opacity: 1, duration: 0.2, ease: 'none' }, 0);

                        introDemo.addEventListener('load', handleIntroReady);
                        introDemo.addEventListener('touchai-component-loaded', handleIntroReady);
                        window.addEventListener('message', handleReadyMessage);

                        return () => {
                            isActive = false;
                            introDemo.removeEventListener('load', handleIntroReady);
                            introDemo.removeEventListener(
                                'touchai-component-loaded',
                                handleIntroReady
                            );
                            window.removeEventListener('message', handleReadyMessage);
                            timeline.scrollTrigger?.kill();
                            timeline.kill();
                        };
                    };

                    const setupFeatureScrollTriggers = (compact) => {
                        const triggers = featureFrames.map((frame) => {
                            const featureBlock = frame.closest('.feature-block') || frame;
                            const featureShell =
                                frame.closest('.feature-block-shell') || featureBlock;
                            let featureTrigger;
                            const syncCurrentFeatureProgress = () => {
                                syncFeatureDemoProgress(frame, featureTrigger?.progress ?? 0);
                            };

                            featureTrigger = ScrollTrigger.create({
                                trigger: featureBlock,
                                start: compact
                                    ? 'top 82%'
                                    : () => {
                                          const shellHeight =
                                              featureShell.getBoundingClientRect().height || 560;
                                          return `top ${Math.max(0, Math.round((window.innerHeight - shellHeight) / 2))}px`;
                                      },
                                end: compact
                                    ? 'bottom 18%'
                                    : () => {
                                          const shellHeight =
                                              featureShell.getBoundingClientRect().height || 560;
                                          return `bottom ${Math.max(0, Math.round((window.innerHeight + shellHeight) / 2))}px`;
                                      },
                                scrub: true,
                                invalidateOnRefresh: true,
                                onRefresh: syncCurrentFeatureProgress,
                                onEnter: syncCurrentFeatureProgress,
                                onEnterBack: syncCurrentFeatureProgress,
                                onUpdate: (self) => {
                                    syncFeatureDemoProgress(frame, self.progress);
                                },
                                onLeave: () => syncFeatureDemoProgress(frame, 1),
                                onLeaveBack: () => syncFeatureDemoProgress(frame, 0),
                            });

                            return featureTrigger;
                        });

                        return () => {
                            triggers.forEach((trigger) => trigger.kill());
                        };
                    };

                    const refreshScrollLayout = () => {
                        requestAnimationFrame(() => {
                            syncFeatureFrameSizing();
                            syncComponentBackground();
                            ScrollTrigger.refresh();
                        });
                    };

                    const scrollMatchMedia = gsap.matchMedia();
                    scrollMatchMedia.add('(max-width: 900px)', () => {
                        const cleanupIntro = setupIntroScrollTrigger(true);
                        const cleanupFeatures = setupFeatureScrollTriggers(true);
                        refreshScrollLayout();

                        return () => {
                            cleanupIntro();
                            cleanupFeatures();
                        };
                    });
                    scrollMatchMedia.add('(min-width: 901px)', () => {
                        const cleanupWorkflow = setupWorkflowPointerEffects();
                        const cleanupIntro = setupIntroScrollTrigger(false);
                        const cleanupFeatures = setupFeatureScrollTriggers(false);
                        refreshScrollLayout();

                        return () => {
                            cleanupWorkflow();
                            cleanupIntro();
                            cleanupFeatures();
                        };
                    });
                }

                const nav = document.querySelector('.nav');
                const syncNavScrolled = () => {
                    nav?.classList.toggle('is-scrolled', window.scrollY > 12);
                };

                window.addEventListener('scroll', syncNavScrolled, { passive: true });

                let resizeTimer;
                window.addEventListener('resize', () => {
                    window.clearTimeout(resizeTimer);
                    resizeTimer = window.setTimeout(() => {
                        syncFeatureFrameSizing();
                        syncComponentBackground();
                        ScrollTrigger.refresh();
                    }, 120);
                });

                window.addEventListener('load', () => {
                    syncNavScrolled();
                    ScrollTrigger.refresh();
                });
            })();
        </script>
    </body>
</html>
