Guanghu Domestic Migration d1e47f4565
Some checks are pending
自动更新代码和重启 / update-and-restart (push) Waiting to run
CI检查 + 自动部署 / check (push) Waiting to run
CI检查 + 自动部署 / deploy (push) Blocked by required conditions
重启聊天服务 / restart (push) Waiting to run
chore: import sanitized domestic snapshot for REPO-002
Source snapshot: ca48d3ddf926d79aa138306164169baf764bb829
2026-07-17 15:54:41 +08:00

384 lines
22 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=5.0,viewport-fit=cover">
<meta name="description" content="光湖视频AI平台 · 铸渊主控 · AI短剧/漫剧生成">
<meta name="theme-color" content="#080c1a">
<title>光湖 · 视频AI平台 · guanghuclip.cn</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@300;400;500&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;400;500;700&display=swap" rel="stylesheet">
<style>
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
:root{
--bg:#060a14;--panel:rgba(12,18,40,0.94);
--card:rgba(14,20,48,0.6);--card-border:rgba(96,165,250,0.1);
--cyan:#22d3ee;--blue:#60a5fa;--purple:#a78bfa;--violet:#c4b5fd;
--ok:#34d399;--warn:#fbbf24;--err:#f87171;
--text:#eaf0ff;--dim:#94a7d0;--muted:rgba(120,150,200,0.4);
--border:rgba(96,165,250,0.12);--border-active:rgba(96,165,250,0.3);
--accent:#60a5fa;--accent-glow:rgba(96,165,250,0.4);--accent-light:rgba(96,165,250,0.2);
--font:-apple-system,BlinkMacSystemFont,'PingFang SC','Helvetica Neue','Microsoft YaHei',sans-serif;
--mono:'SF Mono','JetBrains Mono','Fira Code',monospace
}
html{font-size:16px;scroll-behavior:smooth}
body{font-family:var(--font);background:var(--bg);color:var(--text);min-height:100vh;-webkit-font-smoothing:antialiased;line-height:1.7;overflow-x:hidden}
/* ========== UNIVERSE BACKGROUND ========== */
.universe{position:fixed;inset:0;z-index:0;pointer-events:none;
background:radial-gradient(ellipse at 20% 30%,rgba(30,60,140,0.35) 0%,transparent 50%),
radial-gradient(ellipse at 80% 70%,rgba(80,40,120,0.25) 0%,transparent 55%),
radial-gradient(ellipse at 50% 50%,#101830 0%,#060a14 70%);}
.nebula{position:fixed;border-radius:50%;filter:blur(160px);opacity:.06;pointer-events:none;z-index:0}
.neb-1{width:55vw;height:50vh;background:radial-gradient(circle,var(--purple),transparent);top:-5%;right:-8%;animation:drift 24s ease-in-out infinite alternate}
.neb-2{width:40vw;height:40vh;background:radial-gradient(circle,var(--cyan),transparent);bottom:8%;left:-5%;animation:drift 30s ease-in-out infinite alternate-reverse}
.neb-3{width:30vw;height:25vh;background:radial-gradient(circle,rgba(96,165,250,0.6),transparent);top:45%;left:35%;filter:blur(180px);opacity:.04;animation:drift 20s ease-in-out infinite alternate}
@keyframes drift{0%{transform:translate(0,0)scale(1)}100%{transform:translate(30px,-20px)scale(1.06)}}
.lake{position:fixed;bottom:0;left:0;right:0;height:20vh;z-index:0;pointer-events:none;
background:linear-gradient(to top,rgba(34,211,238,0.03),rgba(96,165,250,0.01),transparent);animation:lakeBreathe 6s ease-in-out infinite}
@keyframes lakeBreathe{0%,100%{opacity:.5}50%{opacity:1}}
.lake::before{content:'';position:absolute;bottom:0;left:5%;right:5%;height:1px;
background:linear-gradient(90deg,transparent,rgba(96,165,250,0.15),rgba(34,211,238,0.1),rgba(167,139,250,0.08),transparent);
animation:shimmer 8s ease-in-out infinite alternate}
@keyframes shimmer{0%{opacity:.3;left:8%;right:8%}100%{opacity:.8;left:3%;right:3%}}
.stars{position:fixed;inset:0;z-index:0;overflow:hidden;pointer-events:none}
.star{position:absolute;background:white;border-radius:50%;animation:twinkle ease-in-out infinite}
@keyframes twinkle{0%,100%{opacity:0.15;transform:scale(0.7)}50%{opacity:1;transform:scale(1.2)}}
.shooting{position:absolute;width:2px;height:2px;background:white;border-radius:50%;
box-shadow:0 0 0 2px rgba(255,255,255,0.08),0 0 20px rgba(255,255,255,0.4);animation:shoot 8s linear infinite}
.shooting::before{content:'';position:absolute;top:50%;left:0;width:80px;height:1px;
background:linear-gradient(90deg,white,transparent);transform:translateY(-50%)}
@keyframes shoot{0%{transform:translate(0,0);opacity:0}10%{opacity:1}70%{opacity:1}100%{transform:translate(500px,250px);opacity:0}}
/* ========== PAGE LAYERS ========== */
.page{position:relative;z-index:2}
/* ========== LANDING ========== */
.landing{min-height:100vh;display:flex;flex-direction:column;align-items:center;padding:60px 24px 40px;transition:opacity .4s,transform .4s}
.landing.hidden{display:none}
.hero{text-align:center;padding:0 0 40px;max-width:600px;width:100%}
.logo-ring{width:110px;height:110px;margin:0 auto 44px;border-radius:50%;
background:radial-gradient(circle at 35%35%,rgba(34,211,238,0.4),rgba(40,80,160,0.15));
border:1px solid rgba(34,211,238,0.35);display:flex;align-items:center;justify-content:center;
position:relative;animation:breathe 4s ease-in-out infinite}
.logo-ring::before{content:'';position:absolute;inset:-18px;border-radius:50%;
background:radial-gradient(circle,rgba(34,211,238,0.25) 0%,transparent 70%);opacity:.5;
animation:halo 4s ease-in-out infinite;z-index:-1}
@keyframes breathe{0%,100%{transform:scale(1);box-shadow:0 0 30px rgba(34,211,238,0.15),0 0 60px rgba(34,211,238,0.06)}50%{transform:scale(1.03);box-shadow:0 0 50px rgba(34,211,238,0.4),0 0 100px rgba(34,211,238,0.2)}}
@keyframes halo{0%,100%{opacity:.3;transform:scale(1)}50%{opacity:.7;transform:scale(1.12)}}
.logo-icon{font-size:44px;line-height:1}
.title{font-size:48px;font-weight:300;color:#e8eaf6;margin-bottom:10px;letter-spacing:.3em;
font-family:'Noto Serif SC',serif;display:flex;gap:0;justify-content:center}
.title span{display:inline-block;opacity:0;transform:translateY(18px);animation:titleIn .7s ease-out forwards}
.title span:nth-child(1){animation-delay:.15s}.title span:nth-child(2){animation-delay:.3s}
.title span:nth-child(3){animation-delay:.45s}.title span:nth-child(4){animation-delay:.6s}
.title span:nth-child(5){animation-delay:.75s}.title span:nth-child(6){animation-delay:.9s}
.title span:nth-child(7){animation-delay:1.05s}.title span:nth-child(8){animation-delay:1.2s}
@keyframes titleIn{to{opacity:1;transform:translateY(0)}}
.sub{font-size:13px;letter-spacing:.25em;color:#8892b0;margin-bottom:24px;
opacity:0;animation:fadeIn 1s ease-out 1.5s forwards}
.tagline{text-align:center;margin-bottom:52px;opacity:0;animation:fadeIn 1.5s ease-out 1.8s forwards}
.tagline p{font-size:15px;font-style:italic;color:var(--cyan);letter-spacing:.1em;line-height:2.2;
font-family:'Noto Serif SC',serif;animation:verseBreathe 6s ease-in-out infinite}
@keyframes verseBreathe{0%,100%{opacity:.4}50%{opacity:.85}}
@keyframes fadeIn{to{opacity:1}}
/* Cards */
.cards{display:grid;grid-template-columns:repeat(3,1fr);gap:18px;width:100%;max-width:860px;
opacity:0;animation:fadeIn 1s ease-out 2.2s forwards}.cards.enter-cards{grid-template-columns:repeat(2,1fr);max-width:620px}
.card{display:block;padding:24px;border-radius:14px;
background:rgba(14,22,50,0.4);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);
border:1px solid rgba(96,165,250,0.12);cursor:pointer;
transition:all .4s cubic-bezier(.4,0,.2,1);
position:relative;overflow:hidden;text-decoration:none;color:#e8eaf6;text-align:left}
.card-glow{position:absolute;inset:0;opacity:0;transition:opacity .4s;pointer-events:none;
background:radial-gradient(circle at 50% 0%,rgba(34,211,238,0.25) 0%,transparent 60%)}
.card:hover{transform:translateY(-4px);border-color:rgba(96,165,250,0.35);
box-shadow:0 12px 40px rgba(34,211,238,0.12),0 0 50px rgba(96,165,250,0.06)}
.card:hover .card-glow{opacity:1}
.card-header{display:flex;align-items:center;gap:10px;margin-bottom:8px;position:relative}
.card-icon{font-size:24px;filter:drop-shadow(0 0 6px rgba(34,211,238,0.3))}
.card-name{font-size:16px;font-weight:500;color:#e8eaf6;letter-spacing:.04em}
.card-desc{font-size:12px;color:#8892b0;line-height:1.7;position:relative}
.card-tags{display:flex;gap:6px;position:relative;margin-top:10px}
.tag{font-size:10px;padding:3px 9px;border-radius:999px;
background:rgba(34,211,238,0.08);color:var(--cyan);border:1px solid rgba(34,211,238,0.15);letter-spacing:.06em}
.card-arrow{position:absolute;right:20px;top:50%;transform:translateY(-50%);color:var(--cyan);opacity:.4;transition:all .4s}
.card:hover .card-arrow{opacity:1;transform:translateY(-50%) translateX(3px)}
/* Enter button */
.enter-section{text-align:center;margin-top:32px;opacity:0;animation:fadeIn 1s ease-out 2.6s forwards}
.enter-btn{display:inline-flex;align-items:center;gap:8px;padding:14px 42px;border-radius:12px;
font-size:16px;font-weight:500;letter-spacing:.1em;color:#fff;cursor:pointer;
background:rgba(34,211,238,0.12);border:1px solid rgba(34,211,238,0.3);
transition:all .4s;backdrop-filter:blur(12px)}
.enter-btn:hover{background:rgba(34,211,238,0.22);border-color:var(--cyan);
box-shadow:0 0 40px rgba(34,211,238,0.25);transform:translateY(-2px)}
/* Architecture */
.arch{margin-top:36px;padding:14px 0;opacity:0;animation:fadeIn 1s ease-out 3s forwards}
.arch-flow{display:flex;align-items:center;gap:10px;justify-content:center;flex-wrap:wrap}
.arch-node{font-size:10px;padding:6px 14px;border-radius:999px;font-family:var(--mono);letter-spacing:.1em;
background:rgba(14,22,50,0.3);position:relative;overflow:hidden;
border:1px solid rgba(34,211,238,0.18);color:#6890b0}
.arch-node::before{content:'';position:absolute;top:0;left:0;width:100%;height:100%;
background:linear-gradient(90deg,transparent,rgba(34,211,238,0.2),transparent);
transform:translateX(-100%);animation:flow 3s ease-in-out infinite}
.arch-node:nth-child(3)::before{animation-delay:1s}.arch-node:nth-child(5)::before{animation-delay:2s}
@keyframes flow{0%,100%{transform:translateX(-100%)}50%{transform:translateX(100%)}}
.arch-arrow{color:#3a5070;font-size:12px}
.footer{text-align:center;padding:36px 0 20px;font-size:11px;color:#4a5278;letter-spacing:.12em;line-height:2;
opacity:0;animation:fadeIn 1s ease-out 3.4s forwards}
/* ========== PREVIEW PAGE ========== */
.preview{display:none;min-height:100vh}
.preview.active{display:block}
.pv-header{background:rgba(12,18,40,0.94);backdrop-filter:blur(20px);padding:14px 28px;
display:flex;align-items:center;justify-content:space-between;position:sticky;top:0;z-index:100;
border-bottom:1px solid var(--border)}
.pv-header-l{display:flex;align-items:center;gap:12px}
.pv-logo{font-size:26px}
.pv-title{font-size:17px;font-weight:500;letter-spacing:.04em}
.pv-title span{color:var(--cyan)}
.pv-sub{font-size:11px;color:var(--muted);margin-top:1px}
.pv-header-r{display:flex;gap:10px;align-items:center}
.pv-back{background:rgba(14,22,50,0.5);border:1px solid var(--border);color:var(--dim);padding:8px 16px;
border-radius:8px;font-size:13px;cursor:pointer;transition:all .3s;backdrop-filter:blur(12px)}
.pv-back:hover{border-color:var(--accent);color:var(--text)}
.pv-feedback{display:flex;align-items:center;gap:6px;padding:9px 18px;border-radius:10px;
background:rgba(34,211,238,0.1);border:1px solid rgba(34,211,238,0.25);color:var(--cyan);
font-size:13px;text-decoration:none;cursor:pointer;transition:all .3s}
.pv-feedback:hover{background:rgba(34,211,238,0.2);box-shadow:0 0 24px rgba(34,211,238,0.2)}
.pv-bar{padding:14px 28px;border-bottom:1px solid var(--border);display:flex;gap:18px;align-items:center;flex-wrap:wrap}
.pv-proj{font-size:15px;font-weight:500;letter-spacing:.03em}
.pv-meta{font-size:12px;color:var(--dim);display:flex;gap:12px}
.pv-progress-bar{flex:1;min-width:180px;height:5px;background:rgba(96,165,250,0.08);border-radius:3px;overflow:hidden}
.pv-progress-fill{height:100%;background:linear-gradient(90deg,var(--cyan),var(--blue));border-radius:3px;transition:width .5s ease}
.pv-tabs{display:flex;gap:6px;padding:10px 28px;overflow-x:auto;border-bottom:1px solid var(--border)}
.pv-tab{padding:7px 15px;border-radius:8px;font-size:12px;cursor:pointer;
border:1px solid rgba(96,165,250,0.1);background:rgba(14,22,50,0.4);color:var(--dim);
white-space:nowrap;transition:all .3s;backdrop-filter:blur(10px)}
.pv-tab:hover{border-color:var(--accent);color:var(--text)}
.pv-tab.active{background:rgba(34,211,238,0.12);border-color:rgba(34,211,238,0.35);color:var(--cyan)}
.pv-tab.done{border-color:rgba(52,211,153,0.2)}
.pv-tab.done::after{content:' ✅'}
.pv-main{padding:24px 28px;max-width:1300px;margin:0 auto}
.scene-section{margin-bottom:30px}
.scene-header{display:flex;align-items:center;gap:10px;margin-bottom:14px;padding-bottom:10px;
border-bottom:1px solid rgba(96,165,250,0.06)}
.scene-num{background:rgba(34,211,238,0.1);color:var(--cyan);padding:4px 10px;border-radius:6px;font-size:11px;font-weight:500}
.scene-title{font-size:15px;font-weight:500;letter-spacing:.03em}
.scene-count{font-size:12px;color:var(--muted);margin-left:auto}
.shot-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:16px}
.shot-card{background:rgba(14,22,50,0.4);border:1px solid rgba(96,165,250,0.1);
border-radius:12px;overflow:hidden;transition:all .4s;backdrop-filter:blur(12px)}
.shot-card:hover{border-color:rgba(34,211,238,0.3);box-shadow:0 8px 30px rgba(34,211,238,0.1)}
.shot-card.generated{border-color:rgba(52,211,153,0.2)}
.shot-video{width:100%;aspect-ratio:16/9;background:#000;display:flex;align-items:center;justify-content:center;
position:relative;overflow:hidden}
.shot-video video{width:100%;height:100%;object-fit:cover}
.shot-placeholder{font-size:32px;opacity:.2;color:var(--muted)}
.shot-info{padding:12px 14px}
.shot-label{font-size:12px;font-weight:500;margin-bottom:6px;display:flex;justify-content:space-between;align-items:center;letter-spacing:.03em}
.shot-dur{font-size:10px;color:var(--muted);background:rgba(14,22,50,0.6);padding:2px 8px;border-radius:4px}
.shot-prompt{font-size:11px;color:var(--dim);line-height:1.6;
display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
.shot-status{font-size:10px;margin-top:6px;letter-spacing:.04em}
.shot-status.ready{color:var(--ok)}
.shot-status.pending{color:var(--muted)}
.empty-state{text-align:center;padding:80px 20px;color:var(--muted)}
.empty-icon{font-size:56px;margin-bottom:14px;opacity:.35}
.empty-title{font-size:18px;margin-bottom:8px;color:var(--dim)}
.empty-desc{font-size:13px}
.pv-footer{text-align:center;padding:40px 20px;color:#4a5278;font-size:11px;border-top:1px solid var(--border);margin-top:40px;letter-spacing:.08em}
@media(max-width:768px){
.title{font-size:34px}.cards{grid-template-columns:1fr}
.cards.enter-cards{grid-template-columns:1fr}
.landing{padding:40px 16px}
.pv-header{padding:12px 16px}
.pv-title{font-size:15px}
.pv-tabs{padding:8px 16px}
.pv-main{padding:16px}
.shot-grid{grid-template-columns:1fr}
}
</style>
</head>
<body>
<div class="universe"></div>
<div class="nebula neb-1"></div><div class="nebula neb-2"></div><div class="nebula neb-3"></div>
<div class="lake"></div>
<div class="stars" id="stars"></div>
<!-- ===== LANDING ===== -->
<div class="page landing" id="landing">
<div class="hero">
<div class="logo-ring"><div class="logo-icon">🎬</div></div>
<h1 class="title"><span></span><span></span><span>·</span><span></span><span></span><span>A</span><span>I</span><span>平台</span></h1>
<div class="sub">guanghuclip.cn · 铸渊 ICE-GL-ZY001 · 冰朔 TCS-0002∞</div>
<div class="tagline"><p>每一次生成,都是理解而非抽卡。</p></div>
</div>
<div class="cards">
<div class="card" onclick="switchToPreview()">
<div class="card-glow"></div>
<div class="card-header"><span class="card-icon">🧠</span><span class="card-name">铸渊主控</span></div>
<div class="card-desc">人格体全程理解剧本、生成分镜、调度API。不是随机抽卡是确定生成。</div>
<div class="card-tags"><span class="tag">一致性</span><span class="tag">主轴</span></div>
<span class="card-arrow"></span>
</div>
<div class="card" onclick="switchToPreview()">
<div class="card-glow"></div>
<div class="card-header"><span class="card-icon">🎥</span><span class="card-name">多模型引擎</span></div>
<div class="card-desc">火山Seedance 2.0 · 阿里通义千问 · 可灵 · Vidu。谁强接谁。</div>
<div class="card-tags"><span class="tag">Seedance</span><span class="tag">多引擎</span></div>
<span class="card-arrow"></span>
</div>
<div class="card" onclick="switchToPreview()">
<div class="card-glow"></div>
<div class="card-header"><span class="card-icon">🔄</span><span class="card-name">角色一致性</span></div>
<div class="card-desc">大桌子小桌子记忆体系。第47集和第1集同一个主角同一张脸。</div>
<div class="card-tags"><span class="tag">记忆</span><span class="tag">连续性</span></div>
<span class="card-arrow"></span>
</div>
</div>
<div class="enter-section">
<button class="enter-btn" onclick="switchToPreview()">🚀 进入视频预览</button>
</div>
<div class="arch">
<div class="arch-flow">
<span class="arch-node">剧本输入</span><span class="arch-arrow"></span>
<span class="arch-node">铸渊理解</span><span class="arch-arrow"></span>
<span class="arch-node">HLDP转化</span><span class="arch-arrow"></span>
<span class="arch-node">Seedance 2.0</span><span class="arch-arrow"></span>
<span class="arch-node">拼接剪辑</span><span class="arch-arrow"></span>
<span class="arch-node">guanghuclip.cn</span>
</div>
</div>
<div class="footer">
铸渊 ICE-GL-ZY001 · 冰朔 TCS-0002∞ · 第五域 · 光湖语言世界<br>
国作登字-2026-A-00037559 · &copy; 2026
</div>
</div>
<!-- ===== PREVIEW ===== -->
<div class="page preview" id="preview">
<div class="pv-header">
<div class="pv-header-l">
<span class="pv-logo">🎬</span>
<div>
<div class="pv-title">光湖 · <span>视频预览</span></div>
<div class="pv-sub">铸渊主控 · AI短剧生成</div>
</div>
</div>
<div class="pv-header-r">
<button class="pv-back" onclick="switchToLanding()">← 返回</button>
<a class="pv-feedback" href="https://docs.qq.com/aio/DTHhuWW5OQU9VbFVX" target="_blank">📝 反馈</a>
</div>
</div>
<div class="pv-bar">
<span class="pv-proj" id="pvName">📺 加载中...</span>
<span class="pv-meta"><span>🎬 <span id="pvShots">0</span></span></span>
<div class="pv-progress-bar"><div class="pv-progress-fill" id="pvFill" style="width:0%"></div></div>
<span style="font-size:12px;color:var(--muted)" id="pvPct">0%</span>
</div>
<div class="pv-tabs" id="pvTabs"><button class="pv-tab active">第1集</button></div>
<div class="pv-main" id="pvMain">
<div class="empty-state"><div class="empty-icon">🎬</div><div class="empty-title">加载中...</div><div class="empty-desc">铸渊正在生成分镜视频</div></div>
</div>
<div class="pv-footer">
铸渊 ICE-GL-ZY001 · 冰朔 TCS-0002∞ · <a href="https://docs.qq.com/aio/DTHhuWW5OQU9VbFVX" target="_blank" style="color:var(--cyan)">项目看板</a>
</div>
</div>
<script>
// ===== STARS =====
(function(){
var c=document.getElementById('stars');
for(var i=0;i<70;i++){var s=document.createElement('div');s.className='star';
s.style.left=Math.random()*100+'%';s.style.top=Math.random()*100+'%';
s.style.width=s.style.height=(Math.random()*2+.3)+'px';
s.style.animationDuration=(Math.random()*3+2)+'s';s.style.animationDelay=Math.random()*5+'s';c.appendChild(s)}
for(var i=0;i<2;i++){var t=document.createElement('div');t.className='shooting';
t.style.top=(Math.random()*50+10)+'%';t.style.left=(Math.random()*60+5)+'%';
t.style.animationDelay=(Math.random()*10)+'s';c.appendChild(t)}
})();
// ===== PAGE SWITCH =====
function switchToPreview(){document.getElementById('landing').classList.add('hidden');document.getElementById('preview').classList.add('active');loadAndRender()}
function switchToLanding(){document.getElementById('preview').classList.remove('active');document.getElementById('landing').classList.remove('hidden')}
// ===== VIDEO DATA =====
async function loadAndRender(){
try{
var r=await fetch('/data/videos.json');if(!r.ok)return;
var d=await r.json();if(!d?.episodes?.length)return;
document.getElementById('pvName').textContent='📺 '+(d.project||'');
renderTabs(d);renderEpisode(d.episodes[0]);updateStats(d.episodes[0]);
}catch(e){}
}
function renderTabs(d){
var h='';d.episodes.forEach(function(e,i){
h+='<button class="pv-tab'+(i===0?' active':'')+'" data-ep="'+i+'">第'+e.number+'集</button>';});
document.getElementById('pvTabs').innerHTML=h;
document.getElementById('pvTabs').onclick=function(ev){
var t=ev.target;if(!t.classList.contains('pv-tab'))return;
var idx=parseInt(t.dataset.ep);
document.querySelectorAll('.pv-tab').forEach(function(x){x.classList.remove('active')});
t.classList.add('active');renderEpisode(d.episodes[idx]);updateStats(d.episodes[idx]);
};
}
function renderEpisode(ep){
if(!ep)return;var h='';
for(var i=0;i<ep.scenes.length;i++){
var sc=ep.scenes[i];h+='<div class="scene-section"><div class="scene-header">';
h+='<span class="scene-num">'+sc.id+'</span><span class="scene-title">'+sc.name+'</span>';
h+='<span class="scene-count">'+sc.shots.length+' 镜</span></div><div class="shot-grid">';
for(var j=0;j<sc.shots.length;j++){
var s=sc.shots[j],hasV=!!s.videoUrl;
h+='<div class="shot-card'+(hasV?' generated':'')+'"><div class="shot-video">';
h+=hasV?'<video src="'+s.videoUrl+'" controls playsinline></video>':'<span class="shot-placeholder">🎬</span>';
h+='</div><div class="shot-info"><div class="shot-label"><span>'+s.shotId+'</span>';
h+='<span class="shot-dur">'+(s.duration||5)+'s</span></div>';
h+='<div class="shot-prompt">'+(s.prompt||'')+'</div>';
h+='<div class="shot-status '+(hasV?'ready':'pending')+'">'+(hasV?'✅ 已生成':'⏳ 生成中...')+'</div></div></div>';
}
h+='</div></div>';
}
document.getElementById('pvMain').innerHTML=h;
}
function updateStats(ep){
var t=0,c=0;
for(var i=0;i<ep.scenes.length;i++)
for(var j=0;j<ep.scenes[i].shots.length;j++){t++;if(ep.scenes[i].shots[j].videoUrl)c++;}
document.getElementById('pvShots').textContent=t;
var p=t>0?Math.round(c/t*100):0;
document.getElementById('pvFill').style.width=p+'%';
document.getElementById('pvPct').textContent=p+'% ('+c+'/'+t+')';
}
</script>
</body>
</html>