games-development-ai/docs-design/huijing-ai-demo.html
zizi 8a59a35133 docs(audit)+docs(mvp): 三向审计修复全链入库——报告+W1回填+创始人拍板波+W2清洗+三件产出
- 审计报告 HJ-AUDIT-001 入库 + W1 文档回填波(技术决策版/Doc B/开发团队版废止横幅/AGENTS.md/两规则档/tech-decisions)
- 创始人拍板波(2026-06-10 晚,回填铁律逐项执行):
  · R4=维持 D2 按 D2 改建(M-c 建 merge→idle→tycoon,动作类降 P1 留契约)→ D2 复审注+tech-decisions #6
  · 鉴权七项全拍(§9.1:C 验证码+邀请码旁路/受限激活/开放注册/创作限白名单/一键登录/实名提现前/纯客户端 anonId)→ glossary+events.schema.json 同步
  · A1 闸门看板建账(12+1 项含短信报备+大模型登记/算法备案/分账选型,主体已确认)+ 律所合规咨询 brief
  · 奇绩 ★1/2/3 定稿 + 品牌造梦→绘境清扫(4 档正文+文件名、demo 改名 huijing-ai-demo.html、禁投/禁外发横幅、内部引用 5 处)
  · M-c 四细节(两批 merge 先行/idle 纯前端+storage/10 校准+20 正式/拖拽为主)
  · R3 收口(叠加规则=IP 从创作者份额出·净额基数·平台恒 20%,eCPM 档 15/30/60)→ D3 复审注+glossary+BP:299 勘误
- W2 对外清洗收口:BP 改造版红线清洗(20 处锁风系红线词清零/独家→非独家/绝对化清零/06-10 实证+三线排序入文,留 3★ 待创始人)
- 三件产出:鉴权 execution 版(V11/system 内扩展/14 @PermitAll 端点/NOT NULL 硬边界)+ Mc 模板波 review 版(已拍)+ 单位经济敏感性模型(基准 324 元/月/千DAU,覆盖基建需 1.33 万 DAU→实证 B 端现金线优先)
- 两本账同步:作战清单(五件拍板项清零)+ 进度总账(三行执行记录)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 08:51:30 +00:00

3714 lines
143 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">
<title>绘境 AI - 产品交互 Demo</title>
<style>
:root {
--bg: #070911;
--panel: #101522;
--panel-2: #151b2b;
--panel-3: #1c2439;
--ink: #eef6ff;
--muted: #8d9ab6;
--line: #2a3551;
--line-2: #34466d;
--cyan: #31e6ff;
--green: #7cf2a4;
--pink: #ff669d;
--amber: #ffc857;
--violet: #9d7cff;
--danger: #ff626f;
--side: 236px;
--radius: 8px;
--shadow: 0 22px 60px rgba(0, 0, 0, .36);
}
* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
margin: 0;
min-height: 100vh;
color: var(--ink);
font-family: Inter, "PingFang SC", "Microsoft YaHei", Arial, sans-serif;
letter-spacing: 0;
overflow-x: hidden;
background:
linear-gradient(90deg, rgba(49, 230, 255, .055) 1px, transparent 1px),
linear-gradient(0deg, rgba(124, 242, 164, .04) 1px, transparent 1px),
radial-gradient(circle at 18% 0%, rgba(49, 230, 255, .13), transparent 34%),
radial-gradient(circle at 80% 6%, rgba(255, 102, 157, .08), transparent 30%),
linear-gradient(135deg, #060711, #0d101a 50%, #061016);
background-size: 42px 42px, 42px 42px, auto, auto, auto;
}
button, input, textarea, select { font: inherit; }
button { border: 0; cursor: pointer; }
input, textarea, select {
width: 100%;
color: var(--ink);
background: rgba(7, 9, 17, .72);
border: 1px solid var(--line-2);
border-radius: var(--radius);
outline: none;
padding: 11px 12px;
}
textarea { min-height: 118px; resize: vertical; line-height: 1.55; }
input:focus, textarea:focus, select:focus {
border-color: rgba(49, 230, 255, .76);
box-shadow: 0 0 0 4px rgba(49, 230, 255, .10);
}
label { display: grid; gap: 8px; color: var(--muted); font-size: 13px; }
h1, h2, h3, p { margin: 0; }
h1 { font-size: clamp(24px, 3.2vw, 40px); line-height: 1.06; }
h2 { font-size: 19px; }
h3 { font-size: 15px; }
p { color: var(--muted); font-size: 13px; line-height: 1.5; }
.shell {
min-height: 100vh;
display: grid;
grid-template-columns: var(--side) minmax(0, 1fr);
}
.sidebar {
position: sticky;
top: 0;
height: 100vh;
padding: 16px 12px;
background: rgba(9, 11, 21, .92);
border-right: 1px solid rgba(49, 230, 255, .16);
backdrop-filter: blur(20px);
display: flex;
flex-direction: column;
gap: 14px;
z-index: 30;
}
.brand {
display: flex;
align-items: center;
gap: 10px;
padding: 8px 8px 14px;
border-bottom: 1px solid var(--line);
}
.brand-icon {
width: 56px;
height: 56px;
flex: 0 0 auto;
display: block;
border-radius: var(--radius);
background: #f7f7f2;
border: 1px solid rgba(255, 255, 255, .26);
box-shadow: 0 10px 26px rgba(0, 0, 0, .18);
}
.brand-wordmark {
width: 146px;
height: 52px;
display: block;
min-width: 0;
}
.create-entry {
min-height: 54px;
border-radius: var(--radius);
color: #061014;
font-weight: 840;
background: linear-gradient(135deg, var(--cyan), var(--green));
box-shadow: 0 16px 34px rgba(49, 230, 255, .18);
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
}
.side-nav {
display: grid;
gap: 7px;
}
.side-nav button {
min-height: 46px;
border-radius: var(--radius);
background: transparent;
color: var(--muted);
display: flex;
align-items: center;
gap: 10px;
padding: 0 10px;
text-align: left;
transition: .18s ease;
}
.side-nav button:hover,
.side-nav button.active {
background: rgba(49, 230, 255, .10);
color: var(--ink);
box-shadow: inset 0 0 0 1px rgba(49, 230, 255, .20);
}
.nav-icon {
width: 24px;
height: 24px;
border: 1px solid currentColor;
border-radius: 7px;
display: grid;
place-items: center;
font-size: 12px;
flex: 0 0 auto;
}
.side-status {
margin-top: auto;
border-radius: var(--radius);
border: 1px solid var(--line);
background: rgba(21, 27, 43, .72);
padding: 12px;
display: grid;
gap: 10px;
}
.main {
min-width: 0;
padding: 12px 14px 32px;
overflow-x: hidden;
}
.topbar {
position: sticky;
top: 0;
z-index: 20;
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
min-height: 68px;
padding-bottom: 12px;
background: linear-gradient(180deg, rgba(7, 9, 17, .98), rgba(7, 9, 17, .78), transparent);
backdrop-filter: blur(16px);
}
.top-tabs {
display: flex;
gap: 8px;
flex-wrap: wrap;
padding: 6px;
border: 1px solid var(--line);
background: rgba(16, 21, 34, .82);
border-radius: var(--radius);
}
.top-tabs button {
min-height: 36px;
border-radius: 7px;
padding: 0 14px;
color: var(--muted);
background: transparent;
white-space: nowrap;
font-weight: 720;
}
.top-tabs button.active {
color: #061014;
background: linear-gradient(135deg, var(--cyan), var(--green));
}
.project-chip {
display: flex;
align-items: center;
gap: 10px;
color: var(--muted);
font-size: 13px;
flex-wrap: wrap;
}
.btn {
min-height: 38px;
border-radius: var(--radius);
padding: 0 14px;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 8px;
color: #061014;
background: linear-gradient(135deg, var(--cyan), var(--green));
font-weight: 820;
white-space: nowrap;
}
.btn.secondary {
background: rgba(21, 27, 43, .90);
color: var(--ink);
border: 1px solid var(--line-2);
}
.btn.hot { background: linear-gradient(135deg, var(--pink), var(--amber)); }
.btn.ghost {
background: rgba(7, 9, 17, .42);
color: var(--muted);
border: 1px solid var(--line);
}
.view { display: none; animation: lift .22s ease both; }
.view.active { display: block; }
@keyframes lift {
from { opacity: 0; transform: translateY(8px); }
to { opacity: 1; transform: translateY(0); }
}
.section-head {
display: flex;
justify-content: space-between;
align-items: flex-end;
gap: 16px;
margin: 8px 0 14px;
}
.panel {
border: 1px solid var(--line);
background: rgba(16, 21, 34, .86);
border-radius: var(--radius);
box-shadow: var(--shadow);
}
.pad { padding: 16px; }
.grid { display: grid; gap: 12px; }
.cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.mini { color: var(--muted); font-size: 12px; }
.ok { color: var(--green); }
.warn { color: var(--amber); }
.danger { color: var(--danger); }
.chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chip {
min-height: 28px;
display: inline-flex;
align-items: center;
gap: 6px;
border-radius: 999px;
border: 1px solid var(--line-2);
padding: 0 10px;
color: var(--muted);
background: rgba(7, 9, 17, .48);
font-size: 12px;
font-weight: 700;
}
.chip.active {
color: #061014;
background: var(--cyan);
border-color: var(--cyan);
}
.status {
display: inline-flex;
align-items: center;
justify-content: center;
min-height: 26px;
border-radius: 999px;
padding: 0 10px;
font-size: 12px;
font-weight: 780;
color: var(--muted);
border: 1px solid var(--line-2);
background: rgba(7, 9, 17, .42);
white-space: nowrap;
}
.status.ok {
color: #061014;
background: var(--green);
border-color: var(--green);
}
.status.warn {
color: #061014;
background: var(--amber);
border-color: var(--amber);
}
.bar {
height: 7px;
border-radius: 999px;
background: rgba(255,255,255,.08);
overflow: hidden;
}
.bar span {
display: block;
height: 100%;
width: var(--value, 0%);
background: linear-gradient(90deg, var(--cyan), var(--green));
}
.hero {
min-height: 318px;
display: grid;
grid-template-columns: minmax(0, 1.15fr) minmax(360px, .85fr);
gap: 14px;
margin-bottom: 14px;
}
.hero-main {
position: relative;
overflow: hidden;
padding: 22px;
border-radius: var(--radius);
border: 1px solid rgba(49, 230, 255, .22);
background:
linear-gradient(135deg, rgba(49, 230, 255, .13), transparent 42%),
linear-gradient(315deg, rgba(255, 102, 157, .10), transparent 38%),
rgba(16, 21, 34, .92);
}
.hero-main::after {
content: "";
display: none;
position: absolute;
right: 18px;
bottom: 18px;
width: 36%;
max-width: 330px;
aspect-ratio: 1.25;
border-radius: var(--radius);
border: 1px solid rgba(49, 230, 255, .22);
background:
linear-gradient(90deg, rgba(49, 230, 255, .20) 1px, transparent 1px),
linear-gradient(0deg, rgba(124, 242, 164, .16) 1px, transparent 1px),
linear-gradient(180deg, rgba(49, 230, 255, .08), rgba(255, 102, 157, .08));
background-size: 22px 22px, 22px 22px, auto;
opacity: .82;
pointer-events: none;
z-index: 0;
}
.hero-main > * {
position: relative;
z-index: 1;
}
.hero-asset-strip {
margin-top: 10px;
padding: 10px;
display: grid;
grid-template-columns: repeat(5, minmax(0, 1fr));
gap: 10px;
border-radius: var(--radius);
border: 1px solid rgba(49, 230, 255, .24);
background: rgba(7, 9, 17, .42);
box-shadow: inset 0 0 0 1px rgba(255,255,255,.03);
}
.hero-asset-card {
min-height: 118px;
border: 1px solid rgba(255,255,255,.14);
border-radius: var(--radius);
padding: 12px;
display: grid;
align-content: space-between;
gap: 10px;
background: linear-gradient(145deg, rgba(255,255,255,.10), rgba(21,27,43,.72));
}
.hero-asset-card strong {
display: block;
font-size: 15px;
line-height: 1.2;
}
.hero-asset-card p {
font-size: 12px;
line-height: 1.45;
}
.hero-asset-pill {
width: 100%;
min-height: 28px;
border-radius: 999px;
display: inline-flex;
align-items: center;
justify-content: center;
color: var(--green);
border: 1px solid rgba(20, 214, 168, .42);
background: rgba(20, 214, 168, .08);
font-size: 12px;
font-weight: 780;
}
.hero-asset-pill.warn {
color: var(--amber);
border-color: rgba(255, 200, 87, .46);
background: rgba(255, 200, 87, .09);
}
.stat-card {
min-height: 126px;
border: 1px solid var(--line);
border-radius: var(--radius);
background: rgba(16, 21, 34, .86);
padding: 14px;
display: grid;
align-content: space-between;
gap: 12px;
}
.stat-card b { font-size: 28px; }
.task {
border: 1px solid var(--line);
border-radius: var(--radius);
padding: 10px;
background: rgba(21, 27, 43, .82);
display: grid;
gap: 8px;
}
.arena-tabs,
.segment,
.creator-tabs {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.arena-tabs button,
.segment button,
.creator-tabs button {
min-height: 36px;
border-radius: var(--radius);
padding: 0 12px;
background: rgba(21, 27, 43, .85);
border: 1px solid var(--line-2);
color: var(--muted);
font-weight: 720;
}
.arena-tabs button.active,
.segment button.active,
.creator-tabs button.active {
color: #061014;
background: linear-gradient(135deg, var(--cyan), var(--green));
border-color: transparent;
}
.game-rows { display: grid; gap: 14px; }
.game-row { display: grid; gap: 10px; }
.game-strip {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 12px;
}
.game-card {
min-height: 236px;
border: 1px solid var(--line);
border-radius: var(--radius);
background: rgba(16, 21, 34, .86);
overflow: hidden;
display: grid;
grid-template-rows: 118px 1fr;
transition: .18s ease;
text-align: left;
color: var(--ink);
}
.game-card:hover {
transform: translateY(-3px);
border-color: rgba(49, 230, 255, .60);
box-shadow: 0 16px 34px rgba(49, 230, 255, .10);
}
.game-cover {
position: relative;
overflow: hidden;
background: linear-gradient(160deg, #18384a, #4c2344 56%, #121626);
}
.game-cover::before {
content: "";
position: absolute;
inset: 18px 28px auto auto;
width: 56px;
height: 56px;
border-radius: 50%;
background: rgba(255, 200, 87, .88);
box-shadow: 0 0 26px rgba(255, 200, 87, .28);
}
.game-cover::after {
content: "";
position: absolute;
left: -8%;
right: -8%;
bottom: 0;
height: 56%;
background: linear-gradient(180deg, rgba(49, 230, 255, .44), rgba(9, 11, 21, .96));
clip-path: polygon(0 100%, 16% 40%, 27% 72%, 42% 25%, 58% 72%, 74% 36%, 100% 100%);
}
.game-cover.ugc { background: linear-gradient(160deg, #1b3d35, #26315e 58%, #111620); }
.game-cover.action { background: linear-gradient(160deg, #2b1b4a, #0e5360 58%, #121626); }
.game-body {
padding: 12px;
display: grid;
gap: 9px;
align-content: space-between;
}
.game-meta {
display: flex;
justify-content: space-between;
gap: 8px;
color: var(--muted);
font-size: 12px;
}
.material-center {
display: grid;
grid-template-columns: 300px minmax(0, 1fr);
gap: 14px;
align-items: start;
}
.material-sidebar {
position: sticky;
top: 84px;
display: grid;
gap: 12px;
align-self: start;
}
.material-workspace {
display: grid;
gap: 14px;
min-width: 0;
}
.material-picker-grid {
display: grid;
grid-template-columns: minmax(0, 1fr) 318px;
gap: 14px;
align-items: stretch;
}
.material-summary {
border: 1px solid rgba(49, 230, 255, .22);
border-radius: var(--radius);
padding: 14px;
background:
linear-gradient(135deg, rgba(49, 230, 255, .12), rgba(124, 242, 164, .05)),
rgba(7, 9, 17, .54);
display: grid;
gap: 8px;
}
.material-summary strong {
font-size: 15px;
color: var(--green);
}
.material-summary p {
font-size: 12px;
line-height: 1.55;
}
.material-summary-metrics {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 8px;
margin-top: 2px;
}
.summary-metric {
border: 1px solid rgba(255,255,255,.08);
border-radius: 10px;
padding: 9px;
background: rgba(0,0,0,.18);
display: grid;
gap: 3px;
}
.summary-metric b {
font-size: 18px;
line-height: 1;
}
.summary-metric span {
color: var(--muted);
font-size: 11px;
}
.material-type-list {
display: grid;
gap: 10px;
margin-top: 12px;
}
.library-btn {
min-height: 78px;
border-radius: var(--radius);
border: 1px solid var(--line);
background: rgba(7, 9, 17, .48);
color: var(--ink);
padding: 12px;
display: grid;
grid-template-columns: 38px minmax(0, 1fr);
align-items: center;
gap: 10px;
text-align: left;
}
.library-btn > span:last-child {
display: grid;
gap: 4px;
min-width: 0;
}
.library-mark {
width: 38px;
height: 38px;
border-radius: 10px;
display: grid;
place-items: center;
color: #061014;
background: linear-gradient(135deg, var(--cyan), var(--green));
font-weight: 900;
}
.library-btn.active {
border-color: rgba(49, 230, 255, .72);
box-shadow: inset 0 0 0 1px rgba(49, 230, 255, .25), 0 14px 30px rgba(49, 230, 255, .08);
background: linear-gradient(135deg, rgba(49, 230, 255, .16), rgba(124, 242, 164, .07));
}
.folder-grid,
.category-grid,
.material-shelf,
.template-card-grid {
display: grid;
gap: 10px;
}
.folder-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.category-grid { grid-template-columns: 1fr; }
.material-shelf { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.folder-card,
.category-card,
.material-card,
.template-card,
.pack-card {
border: 1px solid var(--line);
border-radius: var(--radius);
background: rgba(21, 27, 43, .78);
padding: 12px;
display: grid;
gap: 10px;
color: var(--ink);
text-align: left;
transition: .18s ease;
}
.folder-card {
min-height: 118px;
grid-template-columns: 54px minmax(0, 1fr);
align-items: center;
align-content: start;
}
.folder-card .folder-art {
width: 54px;
height: 54px;
}
.folder-card .status {
width: fit-content;
grid-column: 1 / -1;
}
.category-card {
min-height: 76px;
grid-template-columns: minmax(0, 1fr) auto;
align-items: center;
}
.category-card .status {
border-radius: 8px;
white-space: nowrap;
}
.material-card,
.pack-card {
grid-template-columns: 64px minmax(0, 1fr);
align-items: center;
}
.material-card {
min-height: 118px;
padding: 12px;
}
.material-card strong,
.folder-card strong,
.category-card strong {
font-size: 15px;
line-height: 1.25;
}
.material-card p,
.folder-card p,
.category-card p {
font-size: 12px;
line-height: 1.45;
}
.folder-card.active,
.category-card.active,
.template-card.active,
.pack-card.active {
border-color: rgba(49, 230, 255, .70);
background: linear-gradient(135deg, rgba(49, 230, 255, .13), rgba(21, 27, 43, .86));
}
.folder-art,
.material-thumb,
.asset-thumb,
.pack-thumb {
width: 58px;
height: 58px;
border-radius: var(--radius);
background:
radial-gradient(circle at 34% 32%, rgba(255,255,255,.78) 0 12%, transparent 13%),
radial-gradient(circle at 68% 68%, rgba(255,200,87,.85) 0 12%, transparent 13%),
linear-gradient(135deg, var(--cyan), var(--pink));
border: 1px solid rgba(255,255,255,.10);
flex: 0 0 auto;
}
.material-thumb.scene,
.pack-thumb.scene {
background:
linear-gradient(180deg, rgba(49, 230, 255, .38), transparent 45%),
linear-gradient(145deg, #253a56, #69502f 58%, #161827);
}
.material-thumb.prop,
.pack-thumb.prop {
background:
radial-gradient(circle at 52% 42%, var(--amber) 0 18%, transparent 19%),
linear-gradient(135deg, #173c48, #5f2440);
}
.material-thumb.sound,
.asset-thumb.music {
background:
linear-gradient(90deg, transparent 18%, var(--green) 18% 24%, transparent 24% 42%, var(--cyan) 42% 51%, transparent 51% 68%, var(--amber) 68% 76%, transparent 76%),
#0e1220;
}
.material-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-top: 8px; }
.material-actions .btn { min-height: 30px; padding: 0 10px; }
.material-meta {
display: flex;
flex-wrap: wrap;
gap: 6px;
margin-top: 7px;
}
.material-meta span {
min-height: 22px;
display: inline-flex;
align-items: center;
border-radius: 999px;
padding: 0 8px;
color: var(--muted);
border: 1px solid rgba(255,255,255,.08);
background: rgba(7, 9, 17, .42);
font-size: 11px;
font-weight: 720;
}
.material-shelf-panel {
min-height: 420px;
}
.material-shelf-head {
display: flex;
align-items: flex-end;
justify-content: space-between;
gap: 12px;
margin-bottom: 12px;
}
.material-shelf-tools {
display: flex;
gap: 8px;
flex-wrap: wrap;
justify-content: flex-end;
}
.template-center {
display: grid;
grid-template-columns: 390px minmax(0, 1fr);
gap: 14px;
align-items: start;
}
.template-card {
min-height: 112px;
grid-template-columns: minmax(0, 1fr) auto;
align-items: start;
}
.blueprint {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 10px;
margin-top: 14px;
}
.blueprint-step,
.pipeline-row {
border: 1px solid var(--line);
border-radius: var(--radius);
background: rgba(21, 27, 43, .78);
padding: 12px;
display: flex;
align-items: center;
gap: 10px;
}
.step-index {
width: 30px;
height: 30px;
border-radius: 8px;
display: grid;
place-items: center;
color: #061014;
background: linear-gradient(135deg, var(--cyan), var(--green));
font-weight: 900;
flex: 0 0 auto;
}
.workshop-layout {
display: grid;
gap: 14px;
overflow-x: auto;
}
.workshop-mode { display: none; }
.workshop-mode.active { display: block; }
.dream-workbench {
display: grid;
grid-template-columns: minmax(300px, .82fr) minmax(460px, 1.20fr) minmax(380px, 1fr);
gap: 10px;
align-items: stretch;
min-width: 1140px;
height: calc(100vh - 166px);
min-height: 620px;
}
.work-rail,
.preview-rail {
position: sticky;
top: 84px;
display: grid;
gap: 10px;
align-self: start;
min-width: 0;
height: 100%;
max-height: calc(100vh - 96px);
overflow-y: auto;
overscroll-behavior: contain;
padding-right: 4px;
}
.work-rail .panel,
.agent-center,
.preview-rail .panel {
box-shadow: none;
min-width: 0;
}
.asset-tabs {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 7px;
}
.asset-tabs button,
.mode-card {
border-radius: var(--radius);
border: 1px solid var(--line-2);
background: rgba(7, 9, 17, .52);
color: var(--muted);
font-weight: 720;
}
.asset-tabs button.active,
.mode-card.active {
color: #061014;
background: linear-gradient(135deg, var(--cyan), var(--green));
border-color: transparent;
}
.asset-tabs button {
min-height: 66px;
display: grid;
grid-template-columns: 24px minmax(0, 1fr);
align-items: center;
gap: 7px;
text-align: center;
font-size: 13px;
padding: 8px;
}
.asset-tabs button span {
display: block;
color: inherit;
width: 24px;
height: 24px;
border-radius: 8px;
display: grid;
place-items: center;
background: rgba(255,255,255,.07);
border: 1px solid rgba(255,255,255,.08);
font-size: 14px;
line-height: 1;
}
.asset-tabs button strong {
display: block;
color: inherit;
font-size: 12px;
line-height: 1.2;
text-align: left;
}
.asset-tabs button em {
display: block;
margin-top: 3px;
color: currentColor;
opacity: .68;
font-style: normal;
font-size: 11px;
font-weight: 560;
line-height: 1.25;
text-align: left;
}
.asset-tabs button.active span {
background: rgba(6, 16, 20, .12);
border-color: rgba(6, 16, 20, .18);
}
.asset-list { display: grid; gap: 8px; max-height: 330px; overflow: auto; padding-right: 4px; }
.asset-item {
display: grid;
grid-template-columns: 54px minmax(0, 1fr);
gap: 9px;
align-items: center;
padding: 8px;
border-radius: var(--radius);
border: 1px solid var(--line);
background: rgba(21, 27, 43, .86);
}
.asset-thumb {
width: 54px;
height: 54px;
}
.asset-thumb.fx {
background:
radial-gradient(circle at 36% 42%, var(--cyan) 0 12%, transparent 13%),
radial-gradient(circle at 70% 62%, var(--pink) 0 10%, transparent 11%),
#0e1220;
}
.asset-thumb.ui {
background:
linear-gradient(90deg, rgba(49, 230, 255, .78) 0 22%, transparent 22% 100%),
linear-gradient(180deg, rgba(124, 242, 164, .72) 0 18%, transparent 18% 100%),
#0e1220;
}
.asset-item.generated {
cursor: grab;
transition: .16s ease;
}
.asset-item.generated:hover {
border-color: rgba(49, 230, 255, .70);
transform: translateY(-2px);
}
.role-generator {
display: grid;
gap: 10px;
}
.module-tool {
display: grid;
gap: 10px;
}
.module-tool-panel { display: none; }
.module-tool-panel.active { display: grid; gap: 10px; }
.module-note {
border: 1px solid var(--line);
border-radius: var(--radius);
background: rgba(7, 9, 17, .42);
padding: 10px;
display: grid;
gap: 8px;
}
.module-note strong {
color: var(--ink);
}
.module-note .chip {
width: fit-content;
}
.module-tool textarea {
min-height: 92px;
}
.role-tabs {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 7px;
}
.role-tabs button {
min-height: 34px;
border-radius: var(--radius);
border: 1px solid var(--line-2);
background: rgba(7, 9, 17, .52);
color: var(--muted);
font-weight: 720;
}
.role-tabs button.active {
color: #061014;
background: linear-gradient(135deg, var(--cyan), var(--green));
border-color: transparent;
}
.role-gen-panel { display: none; }
.role-gen-panel.active { display: grid; gap: 10px; }
.task-stack { display: grid; gap: 10px; }
.task-card {
border: 1px solid var(--line);
border-radius: var(--radius);
background: linear-gradient(135deg, rgba(49, 230, 255, .10), rgba(157, 124, 255, .09));
padding: 12px;
display: grid;
gap: 8px;
}
.agent-center {
border: 1px solid rgba(49, 230, 255, .32);
border-radius: var(--radius);
background: rgba(10, 12, 22, .82);
min-height: 0;
height: 100%;
display: grid;
grid-template-rows: auto minmax(0, 1fr) auto;
overflow: hidden;
}
.agent-top {
min-height: 50px;
padding: 9px 10px;
border-bottom: 1px solid var(--line);
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
}
.agent-tabs {
display: inline-flex;
gap: 6px;
padding: 5px;
border-radius: var(--radius);
background: rgba(255,255,255,.04);
border: 1px solid var(--line);
}
.agent-tabs button {
min-height: 28px;
padding: 0 10px;
border-radius: 7px;
color: var(--muted);
background: transparent;
font-size: 13px;
font-weight: 720;
}
.agent-tabs button.active {
color: #061014;
background: rgba(49, 230, 255, .85);
}
.agent-stream {
min-height: 0;
overflow: auto;
padding: 12px;
display: grid;
align-content: start;
gap: 12px;
background:
linear-gradient(90deg, rgba(49, 230, 255, .04) 1px, transparent 1px),
linear-gradient(0deg, rgba(124, 242, 164, .03) 1px, transparent 1px);
background-size: 28px 28px;
}
.agent-message,
.agent-task {
border: 1px solid var(--line);
border-radius: var(--radius);
background: linear-gradient(135deg, rgba(49, 230, 255, .10), rgba(157, 124, 255, .08));
padding: 10px;
display: grid;
gap: 8px;
}
.agent-message p,
.agent-task p {
font-size: 12px;
}
.agent-message.user {
background: rgba(7, 9, 17, .62);
border-color: rgba(49, 230, 255, .36);
}
.agent-task {
grid-template-columns: 36px minmax(0, 1fr) auto;
align-items: center;
}
.agent-task > div:nth-child(2) {
min-width: 0;
}
.agent-icon {
width: 36px;
height: 36px;
border-radius: 8px;
display: grid;
place-items: center;
color: #061014;
background: linear-gradient(135deg, var(--cyan), var(--green));
font-weight: 900;
}
.agent-result-title {
display: inline-flex;
align-items: center;
gap: 8px;
min-width: 0;
}
.agent-result-badge {
width: 26px;
height: 26px;
border-radius: 8px;
display: inline-grid;
place-items: center;
flex: 0 0 auto;
color: #061014;
background: linear-gradient(135deg, var(--cyan), var(--green));
font-size: 12px;
font-weight: 900;
}
.agent-task-chain {
border: 1px solid rgba(49, 230, 255, .42);
border-radius: var(--radius);
background: linear-gradient(135deg, rgba(49, 230, 255, .16), rgba(157, 124, 255, .14));
padding: 10px;
display: grid;
gap: 9px;
max-width: min(94%, 560px);
font-size: 12px;
box-shadow: inset 0 0 0 1px rgba(255,255,255,.035);
}
.task-chain-title,
.task-step-label {
display: inline-flex;
align-items: center;
gap: 7px;
min-width: 0;
}
.task-chain-head .task-chain-title,
.task-chain-row .task-step-label {
display: inline-flex;
}
.task-icon,
.task-step-icon {
width: 24px;
height: 24px;
border-radius: 7px;
display: inline-grid;
place-items: center;
flex: 0 0 auto;
color: #061014;
background: linear-gradient(135deg, var(--cyan), var(--green));
font-size: 12px;
font-weight: 900;
box-shadow: 0 0 18px rgba(49, 230, 255, .16);
}
.task-chain-head {
display: flex;
justify-content: space-between;
align-items: flex-start;
gap: 10px;
}
.task-chain-head strong {
display: block;
font-size: 14px;
color: var(--green);
}
.task-chain-title strong,
.agent-result-title strong {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.task-chain-head p,
.task-chain-row p {
font-size: 11px;
}
.task-chain-toggle {
min-height: 26px;
border-radius: 999px;
padding: 0 9px;
color: var(--ink);
background: rgba(255,255,255,.08);
border: 1px solid rgba(255,255,255,.10);
font-size: 11px;
}
.task-chain-rows {
display: grid;
gap: 6px;
}
.task-chain-row {
display: grid;
grid-template-columns: minmax(154px, .88fr) minmax(112px, 1fr) 36px;
align-items: center;
gap: 8px;
}
.task-chain-row strong {
font-size: 12px;
font-weight: 720;
}
.task-chain-row .task-step-label strong {
color: var(--ink);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.task-chain-row .task-step-icon {
width: 22px;
height: 22px;
font-size: 11px;
}
.task-chain-row .bar {
height: 4px;
background: rgba(0,0,0,.44);
}
.task-chain-row span {
color: var(--muted);
font-size: 11px;
text-align: right;
}
.agent-task-chain.complete {
border-color: rgba(124, 242, 164, .46);
background: linear-gradient(135deg, rgba(124, 242, 164, .13), rgba(49, 230, 255, .10));
}
.agent-composer {
border-top: 1px solid var(--line);
padding: 10px;
display: grid;
gap: 10px;
}
.agent-dropzone {
min-height: 136px;
border: 1px solid rgba(49, 230, 255, .30);
border-radius: var(--radius);
background: rgba(7, 9, 17, .58);
display: grid;
grid-template-rows: auto minmax(72px, 1fr) auto;
overflow: hidden;
transition: .16s ease;
}
.agent-dropzone.dragover {
border-color: var(--cyan);
box-shadow: 0 0 0 4px rgba(49, 230, 255, .10);
background: rgba(49, 230, 255, .08);
}
.attachment-tray {
min-height: 38px;
padding: 8px;
display: flex;
flex-wrap: wrap;
gap: 7px;
border-bottom: 1px solid rgba(255,255,255,.06);
}
.attachment-chip {
min-height: 28px;
border-radius: 999px;
padding: 0 9px;
display: inline-flex;
align-items: center;
gap: 6px;
color: #061014;
background: rgba(49, 230, 255, .88);
font-size: 12px;
font-weight: 760;
}
.agent-input {
width: 100%;
min-height: 66px;
border: 0;
border-radius: 0;
box-shadow: none;
background: transparent;
padding: 10px;
color: var(--ink);
}
.agent-input:focus { box-shadow: none; border: 0; }
.composer-actions {
display: grid;
grid-template-columns: 38px minmax(0, 1fr) 96px;
gap: 7px;
padding: 7px;
border-top: 1px solid rgba(255,255,255,.06);
}
.icon-btn {
min-height: 38px;
border-radius: var(--radius);
color: var(--ink);
background: rgba(21, 27, 43, .90);
border: 1px solid var(--line-2);
font-weight: 900;
}
.helper-select {
min-height: 38px;
padding: 0 10px;
}
.upload-row {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 10px;
}
.upload-tile {
border: 1px dashed rgba(49, 230, 255, .42);
border-radius: var(--radius);
background: rgba(49, 230, 255, .06);
padding: 12px;
display: grid;
gap: 8px;
min-height: 112px;
}
.upload-tile input { padding: 8px; }
.mini-upload {
border: 1px dashed rgba(49, 230, 255, .38);
border-radius: var(--radius);
padding: 10px;
background: rgba(49, 230, 255, .06);
display: grid;
gap: 8px;
}
.module-grid {
display: grid;
grid-template-columns: repeat(6, minmax(0, 1fr));
gap: 8px;
}
.module-card {
min-height: 118px;
border-radius: var(--radius);
border: 1px solid var(--line);
background: rgba(21, 27, 43, .78);
padding: 10px;
display: grid;
align-content: space-between;
gap: 8px;
}
.module-card.active {
border-color: rgba(49, 230, 255, .72);
box-shadow: 0 0 0 3px rgba(49, 230, 255, .08);
}
.preview-frame {
height: 236px;
min-height: 0;
position: relative;
overflow: hidden;
border-radius: var(--radius);
border: 1px solid rgba(49, 230, 255, .24);
background:
linear-gradient(180deg, rgba(49, 230, 255, .20), rgba(9, 11, 21, .10) 42%),
linear-gradient(90deg, rgba(49, 230, 255, .10) 1px, transparent 1px),
linear-gradient(0deg, rgba(124, 242, 164, .08) 1px, transparent 1px),
#0b1020;
background-size: auto, 36px 36px, 36px 36px, auto;
}
.preview-frame::before {
content: "";
position: absolute;
left: -4%;
right: -4%;
bottom: 15%;
height: 30%;
background: linear-gradient(180deg, rgba(124, 242, 164, .48), rgba(7, 9, 17, .92));
clip-path: polygon(0 100%, 15% 42%, 30% 76%, 46% 28%, 61% 70%, 77% 36%, 100% 100%);
}
.actor {
position: absolute;
left: 49%;
top: 38%;
width: 56px;
height: 94px;
border-radius: 44px 44px 10px 10px;
background:
radial-gradient(circle at 50% 18%, #ffd7a8 0 18%, transparent 19%),
linear-gradient(180deg, transparent 0 32%, var(--pink) 32% 68%, #111620 68%);
box-shadow: -17px 15px 0 rgba(124, 242, 164, .72), 17px 17px 0 rgba(49, 230, 255, .68);
}
.preview-caption {
position: absolute;
left: 10px;
right: 10px;
bottom: 10px;
min-height: 58px;
border: 1px solid rgba(49, 230, 255, .24);
border-radius: var(--radius);
padding: 9px;
background: rgba(9, 11, 21, .84);
}
.preview-caption p {
font-size: 12px;
line-height: 1.45;
}
.character-editor {
display: grid;
gap: 7px;
max-height: 178px;
overflow: auto;
padding-right: 4px;
}
.part-row {
min-height: 44px;
border: 1px solid var(--line);
border-radius: var(--radius);
background: rgba(21, 27, 43, .78);
padding: 8px;
display: grid;
grid-template-columns: 40px minmax(0, 1fr) auto;
align-items: center;
gap: 9px;
}
.part-thumb {
width: 40px;
height: 32px;
border-radius: 7px;
background: linear-gradient(135deg, rgba(49, 230, 255, .20), rgba(157, 124, 255, .24));
border: 1px solid rgba(255,255,255,.08);
}
.animation-strip {
display: flex;
gap: 6px;
overflow: auto;
padding-bottom: 2px;
}
.animation-strip button {
min-width: 48px;
min-height: 30px;
border-radius: 8px;
background: rgba(7, 9, 17, .56);
border: 1px solid var(--line);
color: var(--muted);
font-size: 12px;
font-weight: 740;
}
.animation-strip button.active {
color: #061014;
background: var(--cyan);
border-color: var(--cyan);
}
.licensed-workbench {
display: grid;
grid-template-columns: minmax(330px, .92fr) minmax(420px, 1.16fr) minmax(390px, 1fr);
gap: 10px;
align-items: stretch;
min-width: 1140px;
height: calc(100vh - 166px);
min-height: 620px;
}
.licensed-workbench > .grid,
.licensed-dialog-rail,
.licensed-workbench > .preview-rail {
height: 100%;
max-height: calc(100vh - 96px);
overflow-y: auto;
overscroll-behavior: contain;
padding-right: 4px;
}
.licensed-dialog-rail {
position: sticky;
top: 84px;
align-self: start;
min-width: 0;
}
.licensed-dialog-rail .dialog-panel {
margin-top: 0;
min-height: 584px;
display: grid;
grid-template-rows: auto minmax(0, 1fr) auto auto;
background:
linear-gradient(90deg, rgba(49, 230, 255, .04) 1px, transparent 1px),
linear-gradient(0deg, rgba(124, 242, 164, .03) 1px, transparent 1px),
rgba(10, 12, 22, .82);
background-size: 28px 28px, 28px 28px, auto;
box-shadow: none;
}
.licensed-dialog-rail .dialog-stream {
max-height: none;
min-height: 0;
}
.licensed-dialog-rail .dialog-options {
grid-template-columns: 1fr;
}
.licensed-dialog-rail .dialog-composer {
grid-template-columns: minmax(0, 1fr) 88px;
}
.ip-grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 10px;
}
.ip-card {
min-height: 138px;
border: 1px solid var(--line);
border-radius: var(--radius);
background: rgba(21, 27, 43, .80);
padding: 12px;
display: grid;
align-content: space-between;
gap: 10px;
color: var(--ink);
text-align: left;
}
.ip-card.active {
border-color: rgba(49, 230, 255, .70);
background: linear-gradient(135deg, rgba(49, 230, 255, .13), rgba(21, 27, 43, .88));
}
.pack-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 10px;
}
.setting-grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 10px;
}
.launch-grid {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 10px;
}
.launch-card {
min-height: 104px;
border: 1px solid var(--line);
background: rgba(21, 27, 43, .76);
border-radius: var(--radius);
padding: 12px;
display: grid;
align-content: space-between;
gap: 8px;
}
.distribution-panel {
display: grid;
gap: 12px;
}
.distribution-summary {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 8px;
}
.distribution-metric {
min-height: 82px;
border: 1px solid var(--line);
border-radius: var(--radius);
background: rgba(21, 27, 43, .76);
padding: 12px;
display: grid;
align-content: space-between;
gap: 8px;
}
.distribution-metric b {
font-size: 20px;
line-height: 1.1;
}
.distribution-grid {
display: grid;
gap: 10px;
}
.distribution-card {
border: 1px solid var(--line);
border-radius: var(--radius);
background: rgba(21, 27, 43, .76);
padding: 12px;
display: grid;
grid-template-columns: 42px minmax(0, 1fr) auto;
align-items: center;
gap: 10px;
}
.distribution-mark {
width: 42px;
height: 42px;
border-radius: 10px;
display: grid;
place-items: center;
color: #061014;
background: linear-gradient(135deg, var(--cyan), var(--green));
font-size: 16px;
font-weight: 900;
}
.distribution-card strong {
display: block;
font-size: 15px;
line-height: 1.2;
}
.distribution-card p {
font-size: 12px;
line-height: 1.45;
}
.distribution-card .status {
min-width: 74px;
}
.distribution-actions {
display: flex;
gap: 8px;
flex-wrap: wrap;
}
.distribution-actions .btn {
min-height: 32px;
padding: 0 10px;
}
.licensed-debug-head {
align-items: flex-start;
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
gap: 8px;
}
.licensed-debug-actions {
display: inline-flex;
align-items: center;
gap: 6px;
flex-wrap: nowrap;
justify-content: flex-end;
}
.licensed-debug-actions .btn {
min-height: 32px;
padding: 0 10px;
}
.dialog-panel {
margin-top: 12px;
border: 1px solid rgba(49, 230, 255, .28);
border-radius: var(--radius);
background: rgba(7, 9, 17, .50);
overflow: hidden;
}
.dialog-head {
min-height: 44px;
padding: 10px 12px;
border-bottom: 1px solid rgba(255,255,255,.07);
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
}
.dialog-head strong {
font-size: 15px;
}
.dialog-stream {
max-height: 240px;
overflow: auto;
padding: 12px;
display: grid;
gap: 10px;
}
.dialog-bubble {
max-width: 88%;
border: 1px solid var(--line);
border-radius: var(--radius);
padding: 10px 11px;
background: rgba(21, 27, 43, .88);
display: grid;
gap: 5px;
}
.dialog-bubble strong {
font-size: 13px;
}
.dialog-bubble p {
font-size: 12px;
line-height: 1.55;
}
.dialog-bubble.user {
justify-self: end;
border-color: rgba(49, 230, 255, .46);
background: rgba(49, 230, 255, .10);
}
.dialog-options {
padding: 0 12px 12px;
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 8px;
}
.dialog-option {
min-height: 42px;
border-radius: var(--radius);
border: 1px solid var(--line-2);
background: rgba(21, 27, 43, .82);
color: var(--ink);
padding: 8px 10px;
text-align: left;
font-size: 12px;
font-weight: 720;
line-height: 1.35;
}
.dialog-option.active,
.dialog-option:hover {
color: #061014;
background: linear-gradient(135deg, var(--cyan), var(--green));
border-color: transparent;
}
.dialog-composer {
border-top: 1px solid rgba(255,255,255,.07);
padding: 10px;
display: grid;
grid-template-columns: minmax(0, 1fr) 92px;
gap: 8px;
}
.dialog-composer input {
min-height: 38px;
}
.modal-backdrop {
position: fixed;
inset: 0;
z-index: 90;
display: none;
align-items: center;
justify-content: center;
padding: 22px;
background: rgba(3, 5, 12, .74);
backdrop-filter: blur(14px);
}
.modal-backdrop.show { display: flex; }
.modal-card {
width: min(760px, 100%);
max-height: min(720px, calc(100vh - 44px));
overflow: auto;
border: 1px solid rgba(49, 230, 255, .32);
border-radius: var(--radius);
background:
linear-gradient(135deg, rgba(49, 230, 255, .12), rgba(255, 102, 157, .08)),
rgba(12, 16, 28, .98);
box-shadow: 0 26px 80px rgba(0,0,0,.55);
}
.modal-head {
min-height: 64px;
padding: 16px;
border-bottom: 1px solid var(--line);
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 14px;
}
.modal-close {
width: 36px;
min-height: 36px;
border-radius: var(--radius);
color: var(--ink);
background: rgba(7, 9, 17, .62);
border: 1px solid var(--line-2);
font-size: 20px;
line-height: 1;
}
.publish-body {
padding: 16px;
display: grid;
gap: 14px;
}
.publish-summary {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 10px;
}
.publish-metric {
border: 1px solid var(--line);
border-radius: var(--radius);
background: rgba(7, 9, 17, .42);
padding: 10px;
display: grid;
gap: 5px;
}
.channel-grid {
display: grid;
grid-template-columns: repeat(5, minmax(0, 1fr));
gap: 10px;
}
.channel-card {
position: relative;
min-height: 148px;
border: 1px solid var(--line);
border-radius: var(--radius);
background: rgba(21, 27, 43, .78);
padding: 12px;
display: grid;
align-content: space-between;
gap: 10px;
transition: .18s ease;
}
.channel-card.active {
border-color: rgba(49, 230, 255, .76);
box-shadow: inset 0 0 0 1px rgba(49, 230, 255, .22);
background: linear-gradient(135deg, rgba(49, 230, 255, .14), rgba(21, 27, 43, .90));
}
.channel-card.pending {
opacity: .78;
}
.channel-card input {
position: absolute;
opacity: 0;
pointer-events: none;
}
.channel-icon {
width: 38px;
height: 38px;
border-radius: 10px;
display: grid;
place-items: center;
color: #061014;
background: linear-gradient(135deg, var(--cyan), var(--green));
font-weight: 900;
}
.channel-card.pending .channel-icon {
color: var(--muted);
background: rgba(255,255,255,.08);
border: 1px solid rgba(255,255,255,.10);
}
.channel-card strong {
display: block;
font-size: 14px;
line-height: 1.25;
}
.channel-card p {
font-size: 12px;
line-height: 1.45;
}
.channel-check {
width: 24px;
height: 24px;
border-radius: 7px;
display: grid;
place-items: center;
color: #061014;
background: var(--green);
font-size: 14px;
font-weight: 900;
}
.channel-card:not(.active) .channel-check {
color: var(--muted);
background: rgba(255,255,255,.08);
border: 1px solid rgba(255,255,255,.12);
}
.publish-actions {
display: flex;
align-items: center;
justify-content: flex-end;
gap: 8px;
flex-wrap: wrap;
padding-top: 2px;
}
.feed-layout {
display: grid;
grid-template-columns: minmax(540px, 1fr) 340px;
gap: 14px;
align-items: start;
}
.feed-stage {
min-height: 720px;
border-radius: var(--radius);
border: 1px solid var(--line);
background: rgba(4, 5, 12, .74);
display: grid;
grid-template-columns: minmax(360px, 1fr) 96px 78px;
gap: 14px;
align-items: center;
justify-items: center;
padding: 16px;
box-shadow: var(--shadow);
}
.phone {
min-height: 680px;
width: min(390px, 100%);
border-radius: var(--radius);
padding: 10px;
background: #05070d;
border: 1px solid var(--line-2);
box-shadow: 0 20px 55px rgba(0,0,0,.34);
}
.phone-screen {
height: 660px;
border-radius: var(--radius);
position: relative;
overflow: hidden;
background: linear-gradient(180deg, #12344c, #4c2548 56%, #111620);
}
.phone-screen::before {
content: "";
position: absolute;
inset: auto -8% 18%;
height: 38%;
background: linear-gradient(180deg, rgba(49, 230, 255, .52), rgba(7,9,17,.92));
clip-path: polygon(0 100%, 18% 42%, 32% 72%, 49% 24%, 66% 78%, 84% 32%, 100% 100%);
}
.phone-ui {
position: absolute;
inset: auto 0 0;
padding: 18px;
background: linear-gradient(180deg, transparent, rgba(0,0,0,.76) 34%, rgba(0,0,0,.92));
}
.feed-action-rail {
display: grid;
gap: 8px;
justify-items: center;
align-self: center;
}
.feed-action {
width: 72px;
min-height: 70px;
border-radius: 8px;
color: var(--ink);
background: transparent;
display: grid;
place-items: center;
gap: 5px;
text-align: center;
}
.feed-action i {
width: 44px;
height: 44px;
border-radius: 50%;
display: grid;
place-items: center;
background: rgba(255,255,255,.10);
border: 1px solid rgba(255,255,255,.15);
font-style: normal;
font-size: 25px;
box-shadow: 0 12px 28px rgba(0,0,0,.26);
}
.feed-action .bubble-icon {
position: relative;
font-size: 0;
}
.feed-action .bubble-icon::before {
content: "";
width: 23px;
height: 17px;
border-radius: 11px;
border: 2px solid currentColor;
display: block;
}
.feed-action .bubble-icon::after {
content: "";
position: absolute;
left: 18px;
bottom: 11px;
width: 8px;
height: 8px;
border-right: 2px solid currentColor;
border-bottom: 2px solid currentColor;
transform: rotate(28deg);
}
.feed-action strong {
font-size: 13px;
line-height: 1.1;
}
.feed-action span {
color: var(--muted);
font-size: 11px;
line-height: 1.1;
}
.feed-nav {
display: grid;
gap: 28px;
align-self: center;
}
.feed-nav button {
width: 72px;
height: 72px;
border-radius: 50%;
background: rgba(255,255,255,.08);
color: var(--ink);
border: 1px solid rgba(255,255,255,.12);
font-size: 30px;
font-weight: 900;
}
.creator-layout {
display: grid;
grid-template-columns: minmax(0, 1fr) 400px;
gap: 14px;
align-items: start;
}
.chart {
min-height: 240px;
border: 1px solid var(--line);
border-radius: var(--radius);
background: rgba(7, 9, 17, .42);
padding: 16px;
display: flex;
align-items: end;
gap: 12px;
}
.chart div {
flex: 1;
min-height: 32px;
border-radius: 8px 8px 0 0;
background: linear-gradient(180deg, var(--cyan), rgba(49, 230, 255, .12));
}
.b2b-layout {
display: grid;
grid-template-columns: minmax(0, 1fr) 430px;
gap: 14px;
align-items: start;
}
.b2b-box {
border: 1px solid rgba(236, 255, 0, .92);
border-radius: 8px;
padding: 14px;
background: rgba(7, 9, 17, .42);
display: grid;
gap: 12px;
}
.b2b-box .task {
min-height: 104px;
}
.b2b-cases {
display: grid;
gap: 10px;
}
.case-card {
min-height: 90px;
border: 1px solid var(--line);
border-radius: var(--radius);
background: rgba(21, 27, 43, .78);
padding: 12px;
display: grid;
gap: 8px;
}
.profile-layout {
display: grid;
grid-template-columns: 330px minmax(0, 1fr);
gap: 14px;
align-items: start;
}
.setting-row {
border: 1px solid var(--line);
border-radius: var(--radius);
background: rgba(21, 27, 43, .78);
padding: 12px;
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
}
.toast {
position: fixed;
right: 22px;
bottom: 22px;
max-width: min(420px, calc(100vw - 44px));
min-width: 260px;
padding: 14px;
border-radius: var(--radius);
color: #061014;
background: linear-gradient(135deg, var(--cyan), var(--green));
box-shadow: 0 18px 44px rgba(0,0,0,.36);
opacity: 0;
transform: translateY(18px);
pointer-events: none;
transition: .22s ease;
z-index: 80;
font-weight: 760;
}
.toast.show { opacity: 1; transform: translateY(0); }
@media (max-width: 1280px) {
.hero,
.material-center,
.template-center,
.profile-layout,
.feed-layout {
grid-template-columns: 1fr;
}
.material-sidebar { position: static; }
.material-picker-grid { grid-template-columns: minmax(0, 1fr) 300px; }
.game-strip,
.hero-asset-strip,
.folder-grid,
.launch-grid,
.channel-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.distribution-summary { grid-template-columns: 1fr; }
.publish-summary { grid-template-columns: 1fr; }
.module-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.feed-stage { grid-template-columns: 1fr 86px; }
.feed-nav { display: none; }
}
@media (max-width: 1080px) {
.licensed-workbench {
grid-template-columns: 1fr;
min-width: 0;
height: auto;
min-height: 0;
}
.licensed-dialog-rail {
position: static;
grid-column: 1 / -1;
order: 2;
}
.licensed-dialog-rail .dialog-panel {
min-height: 420px;
}
.licensed-workbench > .preview-rail {
order: 3;
}
}
@media (max-width: 1080px) {
.dream-workbench,
.licensed-workbench {
grid-template-columns: 1fr;
min-width: 0;
height: auto;
min-height: 0;
}
.work-rail,
.preview-rail,
.licensed-dialog-rail,
.licensed-workbench > .grid {
position: static;
height: auto;
max-height: none;
overflow: visible;
padding-right: 0;
}
}
@media (max-width: 1080px) {
.creator-layout,
.b2b-layout,
.material-picker-grid {
grid-template-columns: 1fr;
}
}
@media (max-width: 820px) {
:root { --side: 0px; }
.shell { grid-template-columns: 1fr; }
.sidebar {
position: fixed;
left: 10px;
right: 10px;
bottom: 10px;
top: auto;
height: auto;
border: 1px solid var(--line-2);
border-radius: var(--radius);
padding: 8px;
}
.brand,
.side-status { display: none; }
.brand-icon,
.brand-wordmark { height: 48px; }
.side-nav { grid-template-columns: repeat(5, 1fr); }
.side-nav button { justify-content: center; padding: 0 4px; font-size: 12px; }
.side-nav span:not(.nav-icon) { display: none; }
.create-entry { min-height: 42px; }
.main { padding: 12px 12px 92px; }
.topbar { align-items: flex-start; flex-direction: column; }
.section-head { align-items: flex-start; flex-direction: column; }
.game-strip,
.cols-4,
.cols-3,
.cols-2,
.folder-grid,
.hero-asset-strip,
.category-grid,
.distribution-summary,
.material-shelf,
.blueprint,
.upload-row,
.module-grid,
.ip-grid,
.pack-grid,
.setting-grid,
.launch-grid {
grid-template-columns: 1fr;
}
.feed-stage { grid-template-columns: 1fr; }
.feed-action-rail {
grid-template-columns: repeat(4, minmax(0, 1fr));
width: 100%;
}
.material-shelf-head {
align-items: flex-start;
flex-direction: column;
}
.material-shelf-tools {
justify-content: flex-start;
}
.dialog-options,
.channel-grid {
grid-template-columns: 1fr;
}
.composer-actions { grid-template-columns: 1fr; }
.dialog-composer { grid-template-columns: 1fr; }
.phone-screen { height: 590px; }
}
</style>
</head>
<body>
<div class="shell">
<aside class="sidebar">
<div class="brand">
<svg class="brand-icon" viewBox="0 0 128 128" role="img" aria-label="绘境AI 图标">
<rect width="128" height="128" rx="18" fill="#f7f7f2"></rect>
<g fill="none" stroke="#151513" stroke-width="12.5" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 97c-9 0-13-9-12-28l.5-10C11 31 34 11 65 11h19c26 0 43 18 43 47v12c0 27-19 45-46 45h-7c-7 0-11-5-11-12V91c0-7 5-12 12-12h7c12 0 22-9 22-21 0-10-7-18-18-22"></path>
<path d="M42 77c9 11 39 11 51-2"></path>
<path d="M50 29v29"></path>
<path d="M36 44h29"></path>
</g>
<rect x="96" y="39" width="10.5" height="10.5" rx="1.2" fill="#151513" transform="rotate(45 101.25 44.25)"></rect>
</svg>
<svg class="brand-wordmark" viewBox="0 0 172 64" role="img" aria-label="绘境AI 用指令开启万象世界">
<text x="0" y="31" fill="#ffffff" font-size="29" font-weight="900" font-family="PingFang SC, Microsoft YaHei, Arial, sans-serif">绘境AI</text>
<rect x="76" y="22" width="8" height="8" rx="1.5" fill="#ffd21f"></rect>
<text x="2" y="54" fill="#ffffff" font-size="10.5" font-weight="700" letter-spacing="2" font-family="PingFang SC, Microsoft YaHei, Arial, sans-serif">用指令开启万象世界</text>
</svg>
</div>
<button class="create-entry" data-view-jump="workshop"> 创建游戏</button>
<nav class="side-nav" aria-label="左侧主菜单">
<button class="active" data-view-jump="home"><span class="nav-icon"></span><span>首页总览</span></button>
<button data-view-jump="plaza"><span class="nav-icon">广</span><span>游戏广场</span></button>
<button data-view-jump="workshop"><span class="nav-icon">AI</span><span>AI工作坊</span></button>
<button data-view-jump="feed"><span class="nav-icon"></span><span>游戏信息流</span></button>
<button data-view-jump="profile"><span class="nav-icon"></span><span>个人中心</span></button>
</nav>
<div class="side-status">
<span class="mini">当前项目草稿</span>
<strong id="sideProject">让子弹飞一会。。。</strong>
<div class="bar" style="--value: 72%"><span></span></div>
<span class="mini">素材、玩法、调试、上线运营独立编排</span>
</div>
</aside>
<main class="main">
<header class="topbar">
<div class="top-tabs" aria-label="顶部业务中心">
<button data-top-jump="plaza">游戏广场</button>
<button data-top-jump="materials">素材中心</button>
<button data-top-jump="templates">玩法模版中心</button>
<button data-top-jump="creator">创作者中心</button>
<button data-top-jump="b2b">B端定制中心</button>
</div>
<div class="project-chip">
<span id="currentLocation">首页总览</span>
<span>AP2 生产中</span>
<button class="btn secondary" id="quickPlay">试玩当前游戏</button>
</div>
</header>
<section class="view active" id="home">
<div class="hero">
<div class="hero-main">
<div class="chips">
<span class="chip active">现象级授权 IP</span>
<span class="chip">UGC 孵化 IP</span>
<span class="chip">独立素材中心</span>
<span class="chip">独立模板中心</span>
</div>
<h1 style="margin:16px 0 12px;">绘境 AI从素材货架到游戏工作台的完整生产平台</h1>
<p style="max-width:720px;">新版结构将“看游戏”“选素材”“选玩法”“做游戏”“看数据”拆成清晰页面。创作者可以先在素材中心采购/选用素材,也可以在工作坊直接用 AI 生成图元、角色、特效、场景、界面和音乐。</p>
<div class="chips" style="margin-top:22px;">
<button class="btn" data-view-jump="workshop">创建游戏</button>
<button class="btn secondary" data-view-jump="plaza">浏览游戏广场</button>
<button class="btn ghost" data-view-jump="materials">进入素材中心</button>
</div>
<div class="hero-asset-strip" aria-label="核心资产生产能力">
<div class="hero-asset-card">
<div><strong>图元</strong><p>一键生成统一画风整套美术资源</p></div>
<span class="hero-asset-pill">批量</span>
</div>
<div class="hero-asset-card">
<div><strong>角色</strong><p>骨骼拼接、动作流畅和表现调参</p></div>
<span class="hero-asset-pill">可调</span>
</div>
<div class="hero-asset-card">
<div><strong>特效</strong><p>技能、场景、氛围特效快速套用</p></div>
<span class="hero-asset-pill warn">生成中</span>
</div>
<div class="hero-asset-card">
<div><strong>场景</strong><p>城镇、关卡、剧情界面快速搭建</p></div>
<span class="hero-asset-pill">已入库</span>
</div>
<div class="hero-asset-card">
<div><strong>界面</strong><p>按钮、弹窗、状态栏整套 UI 完成</p></div>
<span class="hero-asset-pill">可发布</span>
</div>
</div>
</div>
<div class="panel pad">
<h2>产品路径总览</h2>
<div class="grid" style="margin-top:14px;">
<div class="task"><strong>素材中心</strong><p>授权 IP 素材库与 UGC 孵化素材库独立浏览、选用、采购。</p><div class="bar" style="--value:86%"><span></span></div></div>
<div class="task"><strong>玩法模板中心</strong><p>经营模拟、剧情互动、解谜闯关、TRPG 跑团、非遗科普独立选型。</p><div class="bar" style="--value:78%"><span></span></div></div>
<div class="task"><strong>AI 工作坊</strong><p>自定义创作与现象级授权 IP 创作两套流程,完成生成、调试和上线运营。</p><div class="bar" style="--value:91%"><span></span></div></div>
</div>
</div>
</div>
<div class="grid cols-4">
<div class="stat-card"><span class="mini">广场可玩游戏</span><b>328</b><span class="ok">双专区已上线</span></div>
<div class="stat-card"><span class="mini">授权 IP 素材</span><b>24.8k</b><span class="ok">王蓝莓 / 起重集 / 小蓝</span></div>
<div class="stat-card"><span class="mini">UGC 孵化项目</span><b>1,286</b><span class="warn">本周新增 94</span></div>
<div class="stat-card"><span class="mini">调试通过率</span><b>94.6%</b><span class="ok">锁风 + 性能 + 版权</span></div>
</div>
</section>
<section class="view" id="plaza">
<div class="section-head">
<div>
<h1>游戏广场</h1>
<p>按现象级 IP 与 UGC 孵化 IP 分区浏览,优秀素材案例、新游推荐、全部游戏均可点击试玩。</p>
</div>
<div class="arena-tabs">
<button class="active" data-zone="licensed">现象级IP专区</button>
<button data-zone="ugc">UGC 孵化IP专区</button>
</div>
</div>
<div class="game-rows" id="gameRows"></div>
</section>
<section class="view" id="materials">
<div class="section-head">
<div>
<h1>素材中心</h1>
<p>独立素材货架,用于创作者选用或采购素材;这里不承担工作坊生成流程。</p>
</div>
<div class="chips">
<button class="btn secondary" id="assetQuote">采购授权包</button>
<button class="btn" id="assetUse">加入项目草稿</button>
</div>
</div>
<div class="material-center">
<aside class="material-sidebar">
<div class="panel pad">
<h2>素材库类型</h2>
<div class="material-type-list">
<button class="library-btn active" data-library="licensed">
<span class="library-mark">IP</span>
<span><strong>授权 IP 素材库</strong><span class="mini">正版授权 / 可商用 / 可分成</span></span>
</button>
<button class="library-btn" data-library="ugc">
<span class="library-mark">UGC</span>
<span><strong>UGC 孵化 IP素材库</strong><span class="mini">原创沉淀 / 二次孵化 / 可采购</span></span>
</button>
</div>
</div>
<div class="material-summary">
<strong id="librarySummaryTitle">授权 IP 素材库</strong>
<p id="librarySummaryText">包含王蓝莓 IP、起重集 IP、小蓝 IP素材带授权范围、锁风标签和商业化分成规则。</p>
<div class="material-summary-metrics">
<div class="summary-metric"><b id="librarySummaryCount">24.8k</b><span>可用素材</span></div>
<div class="summary-metric"><b id="librarySummaryAuth">98%</b><span>授权完整率</span></div>
</div>
<div class="chips">
<span class="chip active">可选用</span>
<span class="chip">可采购</span>
<span class="chip">可进草稿</span>
</div>
</div>
</aside>
<section class="material-workspace">
<div class="material-picker-grid">
<div class="panel pad">
<div class="section-head" style="margin-top:0;">
<div>
<h2 id="folderTitle">授权 IP 分组</h2>
<p id="folderSubtitle">点击王蓝莓、起重集、小蓝任意 IP 查看四类素材。</p>
</div>
<span class="status ok">先选 IP</span>
</div>
<div class="folder-grid" id="folderGrid"></div>
</div>
<div class="panel pad">
<div class="section-head" style="margin-top:0;">
<div>
<h2>四类素材</h2>
<p>按授权包归档,选择后下方货架同步刷新。</p>
</div>
</div>
<div class="category-grid" id="categoryGrid"></div>
</div>
</div>
<div class="panel pad material-shelf-panel">
<div class="material-shelf-head">
<div>
<h2 id="shelfTitle">王蓝莓 IP素材 / 角色原画素材</h2>
<p>用于选品、授权采购和项目草稿沉淀;进入工作坊后可再生成补充资产。</p>
</div>
<div class="material-shelf-tools">
<span class="chip active">货架预览</span>
<span class="chip">授权可查</span>
<span class="chip">风格锁定</span>
</div>
</div>
<div class="material-shelf" id="materialShelf"></div>
</div>
</section>
</div>
</section>
<section class="view" id="templates">
<div class="section-head">
<div>
<h1>玩法模板中心</h1>
<p>独立模板库,用于浏览、收藏、购买和应用玩法框架;工作坊只读取选择结果。</p>
</div>
<button class="btn" id="templateUse">应用模板到草稿</button>
</div>
<div class="template-center">
<div class="panel pad">
<h2>玩法模板</h2>
<div class="template-card-grid" id="templateList" style="margin-top:12px;"></div>
</div>
<div class="panel pad">
<div class="section-head" style="margin-top:0;">
<div>
<h2 id="templateDetailTitle">经营模拟</h2>
<p id="templateDetailDesc">围绕资源投入、设施升级、顾客反馈和阶段收益构建轻量循环。</p>
</div>
<span class="status ok" id="templateFit">适配:王蓝莓 IP</span>
</div>
<div class="blueprint" id="templateBlueprint"></div>
<div class="panel pad" style="box-shadow:none; margin-top:14px;">
<h2>模板配置</h2>
<div class="grid cols-2" style="margin-top:12px;">
<label>推荐时长
<select><option>60 秒</option><option selected>90 秒</option><option>3 分钟</option></select>
</label>
<label>运营点位
<select><option>结算页激励视频</option><option selected>关卡失败复活</option><option>皮肤付费</option></select>
</label>
</div>
<div class="chips" style="margin-top:14px;">
<button class="btn" id="applyTemplateBtn">应用到工作坊</button>
<button class="btn secondary" id="favoriteTemplate">收藏模板</button>
<button class="btn ghost" id="buyTemplate">购买商用模板</button>
</div>
</div>
</div>
</div>
</section>
<section class="view" id="workshop">
<div class="section-head">
<div>
<h1>AI工作坊</h1>
<p>这里只处理“制作游戏”:自定义创作生成 UGC 孵化 IP授权 IP 创作进入现象级 IP 专区。</p>
</div>
<div class="segment" id="workshopModeTabs">
<button class="active" data-workshop-mode="custom">自定义创作</button>
<button data-workshop-mode="licensed">现象级授权IP创作</button>
</div>
</div>
<div class="workshop-layout">
<div class="workshop-mode active" data-workshop-pane="custom">
<div class="dream-workbench">
<aside class="work-rail">
<div class="panel pad">
<div class="section-head" style="margin:0 0 10px;">
<div><h2>六类资产模块</h2><p>图元、角色、特效、场景、界面、音乐均可生成、拖拽和作为附件识别。</p></div>
<span class="status ok">AP1</span>
</div>
<div class="asset-tabs" id="customAssetTabs"></div>
</div>
<div class="panel pad">
<div class="section-head" style="margin:0 0 10px;">
<div><h2 id="moduleToolTitle">角色模块</h2><p id="moduleToolDesc">支持图片描述与文本描述生成角色,拖入输入框后智能体会按角色画风生成游戏。</p></div>
<span class="status warn" id="moduleToolStatus">可拖拽</span>
</div>
<div class="module-tool">
<div class="module-note" id="moduleToolNote">
<strong>角色骨骼与画风识别</strong>
<p>生成后自动拆分基础动作、主体比例和配色风格,可直接拖入中间输入框作为用户附件。</p>
<div class="chips"><span class="chip active">图生角色</span><span class="chip">文生角色</span><span class="chip">附件识别</span></div>
</div>
<div class="module-tool-panel active" data-module-panel="role">
<div class="role-generator">
<div class="role-tabs" id="roleGenTabs">
<button class="active" data-role-gen="image">图片描述</button>
<button data-role-gen="text">文本描述</button>
</div>
<div class="role-gen-panel active" data-role-gen-panel="image">
<div class="mini-upload">
<strong>上传角色参考图</strong>
<p>识别主体、服饰、比例和画风,生成可拖拽角色素材。</p>
<input type="file" id="customImageUpload" accept="image/*">
</div>
</div>
<div class="role-gen-panel" data-role-gen-panel="text">
<label>角色文字描述
<textarea id="roleTextPrompt">银蓝色机甲少年,发光耳机,轻科幻街机风,适合横版动作和剧情互动。</textarea>
</label>
</div>
<div class="grid cols-2">
<button class="btn" id="generateRoleBtn">生成角色</button>
<button class="btn secondary" id="clearRolePrompt">清空</button>
</div>
</div>
</div>
<div class="module-tool-panel" data-module-panel="generic">
<label><span id="modulePromptLabel">资产生成描述</span>
<textarea id="moduleAssetPrompt">生成一组统一画风的游戏资产,适配剧情互动与轻解谜玩法。</textarea>
</label>
<div class="upload-row" style="grid-template-columns: 1fr;">
<div class="upload-tile"><strong id="moduleUploadTitle">上传参考素材</strong><p id="moduleUploadText">可上传图片或视频提取风格、结构和动态节奏。</p><input type="file" id="moduleAssetUpload" accept="image/*,video/*,audio/*"></div>
</div>
<button class="btn" id="generateModuleAsset">生成当前模块资产</button>
</div>
</div>
</div>
<div class="panel pad">
<div class="section-head" style="margin:0 0 10px;">
<div><h2 id="assetListTitle">角色素材</h2><p>点击或拖拽素材到智能体输入框即可作为用户附件使用。</p></div>
</div>
<div class="asset-list" id="customAssetList"></div>
</div>
</aside>
<section class="agent-center">
<div class="agent-top">
<div>
<strong>新建项目1</strong>
<p>AP1 框架游戏 / 自定义创作</p>
</div>
<div class="agent-tabs">
<button class="active">绘境引擎</button>
<button>所有素材</button>
<button>代码目录</button>
</div>
</div>
<div class="agent-stream" id="agentStream">
<div class="agent-message">
<strong>绘境智能体</strong>
<p>把左侧生成好的角色拖到下方输入框,或直接描述游戏需求。我会识别附件角色的画风、骨骼方向和适配玩法,再生成游戏。</p>
</div>
<div class="agent-message user">
<strong>创作目标</strong>
<p>做一个校园奇想原创 IP主角在屋顶电台收集同学心愿通过剧情互动和轻解谜修复旧广播最终让校园晚会重新开场。</p>
</div>
</div>
<div class="agent-composer">
<div class="agent-dropzone" id="agentDropzone">
<div class="attachment-tray" id="attachmentTray">
<span class="mini">用户附件:可拖入左侧角色、图元、场景或上传图片/视频</span>
</div>
<textarea class="agent-input" id="customPrompt">将拖入的角色作为主角,保持角色画风,生成一款剧情互动 + 轻解谜小游戏:屋顶电台、心愿收集、广播修复、晚会开场。</textarea>
<div class="composer-actions">
<button class="icon-btn" id="attachFileBtn" title="上传附件"></button>
<select class="helper-select" id="customTemplateSelect">
<option>剧情互动</option>
<option>经营模拟</option>
<option>解谜闯关</option>
<option>TRPG跑团</option>
<option>非遗科普</option>
</select>
<button class="btn hot" id="runCustomProduction">发送</button>
</div>
</div>
<input type="file" id="customFileUpload" accept="image/*,video/*" hidden>
</div>
</section>
<aside class="preview-rail">
<div class="panel pad">
<div class="section-head licensed-debug-head" style="margin-top:0;">
<div><h2>实时预览</h2><p>角色画风、场景和交互节点会同步刷新。</p></div>
<div class="licensed-debug-actions">
<button class="btn hot" id="customLaunchAll">一键发布</button>
<button class="btn secondary" id="customPublishSettings">设置</button>
<span class="status warn" id="customPreviewStatus">草稿</span>
</div>
</div>
<div class="preview-frame">
<div class="actor"></div>
<div class="preview-caption">
<strong id="customSpeaker">屋顶电台</strong>
<p id="customStageText">今晚的广播突然恢复了信号,先修天线还是先找留言本?</p>
</div>
</div>
<div class="animation-strip" style="margin-top:12px;">
<button class="active">待机</button>
<button>行走</button>
<button>攻击</button>
<button>受击</button>
<button>互动</button>
<button>结算</button>
</div>
</div>
<div class="panel pad">
<div class="section-head" style="margin:0 0 10px;">
<div><h2>角色编辑</h2><p>拆件、动作、表现效果可继续调节。</p></div>
<button class="btn secondary" id="exportAnimation">导出</button>
</div>
<div class="character-editor" id="characterParts"></div>
</div>
</aside>
</div>
</div>
<div class="workshop-mode" data-workshop-pane="licensed">
<div class="licensed-workbench">
<section class="grid">
<div class="panel pad">
<div class="section-head" style="margin-top:0;">
<div><h2>1. 选择现象级授权 IP</h2><p>从素材中心已授权 IP 中选择项目母体,再进入模板和资产配置。</p></div>
<button class="btn hot" id="runLicensedProduction">生成授权IP试玩版</button>
</div>
<div class="ip-grid" id="licensedIpGrid"></div>
</div>
<div class="panel pad">
<h2>2. 选择玩法模板</h2>
<div class="segment" id="licensedTemplateTabs" style="margin-top:12px;"></div>
</div>
<div class="panel pad">
<h2>3. 已授权美术与功能包</h2>
<p>这里调用素材中心已授权资产,也允许补充自定义生成与导入。</p>
<div class="pack-grid" id="licensedPackGrid" style="margin-top:12px;"></div>
</div>
<div class="panel pad">
<h2>4. 自定义补充资产</h2>
<div class="setting-grid" style="margin-top:12px;">
<label>图元设定<input value="年代小卖部贴纸、货架图标、任务徽章"></label>
<label>角色设定<input value="主角、同学、邻居三套动作"></label>
<label>音乐设定<input value="怀旧 BGM + 顾客进门铃"></label>
</div>
<div class="upload-row" style="margin-top:12px;">
<div class="upload-tile"><strong>导入图片</strong><p>补充角色或场景参考。</p><input type="file" id="licensedImageUpload" accept="image/*"></div>
<div class="upload-tile"><strong>导入视频</strong><p>提取镜头和动作节奏。</p><input type="file" id="licensedVideoUpload" accept="video/*"></div>
<label>目标专区
<select id="licensedLaunchZone">
<option selected>现象级IP专区 + 游戏信息流</option>
<option>现象级IP专区内测</option>
<option>仅保存为授权草稿</option>
</select>
</label>
</div>
</div>
</section>
<section class="licensed-dialog-rail">
<div class="dialog-panel" aria-label="授权 IP 互动对白调试">
<div class="dialog-head">
<div><strong>交互式对话框</strong><p>选择对白分支,实时刷新试玩预览。</p></div>
<span class="status ok" id="licensedDialogStatus">分支待确认</span>
</div>
<div class="dialog-stream" id="licensedDialogStream">
<div class="dialog-bubble">
<strong>王蓝莓</strong>
<p>今天的小卖部要开张啦,先进汽水还是先摆辣条?</p>
</div>
<div class="dialog-bubble user">
<strong>玩家</strong>
<p>先把最容易卖爆的货上架,再留一个隐藏任务给老同学。</p>
</div>
</div>
<div class="dialog-options" id="licensedDialogOptions">
<button class="dialog-option active" data-dialog-option="先进汽水,触发清凉促销任务。">先进汽水,触发清凉促销任务。</button>
<button class="dialog-option" data-dialog-option="先摆辣条,解锁同桌回忆支线。">先摆辣条,解锁同桌回忆支线。</button>
<button class="dialog-option" data-dialog-option="询问老同学愿望,开启心愿收集。">询问老同学愿望,开启心愿收集。</button>
<button class="dialog-option" data-dialog-option="检查授权台词,进入人工复核。">检查授权台词,进入人工复核。</button>
</div>
<div class="dialog-composer">
<input id="licensedDialogInput" value="先把玻璃汽水摆到门口,吸引放学路过的同学。">
<button class="btn hot" id="licensedDialogSend">发送</button>
</div>
</div>
</section>
<aside class="preview-rail">
<div class="panel pad">
<div class="section-head licensed-debug-head" style="margin-top:0;">
<div><h2>授权 IP 调试台</h2><p>锁风、版权、模板节点和上线运营统一检查。</p></div>
<div class="licensed-debug-actions">
<button class="btn hot" id="licensedLaunchAll">一键发布</button>
<button class="btn secondary" id="licensedPublishSettings">设置</button>
<span class="status ok" id="licensedPreviewStatus">已授权</span>
</div>
</div>
<div class="preview-frame">
<div class="actor"></div>
<div class="preview-caption">
<strong id="licensedSpeaker">王蓝莓</strong>
<p id="licensedStageText">今天的小卖部要开张啦,先进汽水还是先摆辣条?</p>
</div>
</div>
<div class="grid" style="margin-top:12px;">
<label>授权剧情对白草稿
<textarea id="licensedDialogue">今天的小卖部要开张啦,先进汽水还是先摆辣条?</textarea>
</label>
<div class="grid cols-2">
<label>锁风强度<select><option>标准</option><option selected>严格</option><option>人工复核</option></select></label>
<label>调试动作<select><option>idle</option><option selected>walk</option><option>skill</option><option>hurt</option></select></label>
</div>
</div>
</div>
</aside>
</div>
</div>
</div>
</section>
<section class="view" id="feed">
<div class="section-head">
<div>
<h1>游戏信息流</h1>
<p>竖屏即刷即玩,支持同款创作、点赞、评论和跳转广场。</p>
</div>
<div class="chips">
<button class="btn secondary" id="prevFeed">上一条</button>
<button class="btn" id="nextFeed">下一条</button>
</div>
</div>
<div class="feed-layout">
<div class="feed-stage">
<div class="phone">
<div class="phone-screen">
<div class="phone-ui">
<div class="chips" id="feedTags"></div>
<h2 id="feedTitle">王蓝莓:复古小卖部</h2>
<p id="feedDesc">经营复古小卖部,招待邻居,解锁限定贴纸。</p>
<div class="grid cols-3" style="margin-top:12px;">
<div><strong id="feedPlay">38.2k</strong><p>游玩</p></div>
<div><strong id="feedFinish">42%</strong><p>完玩</p></div>
<div><strong id="feedZone">现象级IP</strong><p>专区</p></div>
</div>
</div>
</div>
</div>
<div class="feed-action-rail" aria-label="信息流互动动作">
<button class="feed-action" id="followBtn"><i></i><strong>关注</strong><span id="feedActionFollow">12.8万</span></button>
<button class="feed-action" id="playActionBtn"><i></i><strong>游玩</strong><span id="feedActionPlay">18.6万</span></button>
<button class="feed-action" id="likeBtn"><i></i><strong>点赞</strong><span id="feedActionLike">3.2万</span></button>
<button class="feed-action" id="commentBtn"><i class="bubble-icon"></i><strong>评论</strong><span id="feedActionComment">5126</span></button>
<button class="feed-action" id="collectBtn"><i></i><strong>收藏</strong><span id="feedActionCollect">8963</span></button>
<button class="feed-action" id="shareBtn"><i></i><strong>分享</strong><span id="feedActionShare">2415</span></button>
<button class="feed-action" id="favoriteBtn"><i></i><strong>最喜欢</strong><span id="feedActionFavorite">7689</span></button>
</div>
<div class="feed-nav" aria-label="切换信息流">
<button id="prevFeedStage"></button>
<button id="nextFeedStage"></button>
</div>
</div>
<div class="panel pad">
<h2>信息流推荐池</h2>
<div class="grid" id="feedList" style="margin-top:12px;"></div>
</div>
</div>
</section>
<section class="view" id="creator">
<div class="section-head">
<div>
<h1>创作者中心</h1>
<p>创作者智能数据后台全维度留存、广告转化数据看板AI 自动诊断内容短板并支持一键迭代优化。</p>
</div>
<button class="btn" id="optimizeBtn">一键迭代优化</button>
</div>
<div class="creator-layout">
<section class="grid">
<div class="grid cols-4">
<div class="stat-card"><span class="mini">次日留存</span><b>31.8%</b><span class="ok">较同类 +6.4%</span></div>
<div class="stat-card"><span class="mini">完玩率</span><b>46.2%</b><span class="warn">第 3 节点流失高</span></div>
<div class="stat-card"><span class="mini">广告转化</span><b>8.7%</b><span class="ok">复活位最佳</span></div>
<div class="stat-card"><span class="mini">素材复用</span><b>126</b><span class="ok">本周 +24</span></div>
</div>
<div class="grid cols-2">
<div class="panel pad">
<h2>七日留存与播放趋势</h2>
<div class="chart" style="margin-top:12px;">
<div style="height:42%"></div><div style="height:55%"></div><div style="height:48%"></div><div style="height:64%"></div><div style="height:78%"></div><div style="height:70%"></div><div style="height:86%"></div>
</div>
</div>
<div class="panel pad">
<h2>AI 内容诊断</h2>
<div class="grid" style="margin-top:12px;">
<div class="pipeline-row"><div><strong>首屏任务不够明确</strong><p>建议前 5 秒加入倒计时目标和道具反馈。</p></div><span class="status warn">P1</span></div>
<div class="pipeline-row"><div><strong>第 3 节点对白过长</strong><p>建议拆成 2 次选择,降低跳出。</p></div><span class="status warn">P2</span></div>
<div class="pipeline-row"><div><strong>广告转化稳定</strong><p>结局后展示不明显影响完玩率。</p></div><span class="status ok">保留</span></div>
</div>
</div>
</div>
</section>
<aside class="panel pad">
<h2>数据后台</h2>
<div class="grid" style="margin-top:12px;">
<div class="task"><strong>本周迭代建议</strong><p>优先优化开场任务、缩短对白、增加可收集贴纸。</p><button class="btn secondary" id="makeIteration">生成改版任务</button></div>
<div class="task"><strong>广告转化短板</strong><p>失败复活点位点击高,结算页二跳略弱。</p><span class="status warn">待优化</span></div>
<div class="task"><strong>AI 自动诊断</strong><p>预计可将首屏完玩率提升 5.8%,建议生成 A/B 测试版本。</p><span class="status ok">可执行</span></div>
</div>
</aside>
</div>
</section>
<section class="view" id="b2b">
<div class="section-head">
<div>
<h1>B端定制中心</h1>
<p>独立承接文旅、政务、快消品牌、短剧平台的定制项目需求,和创作者数据后台分开管理。</p>
</div>
<button class="btn hot" id="submitDemand">提交定制需求</button>
</div>
<div class="b2b-layout">
<section class="panel pad">
<div class="b2b-box">
<div>
<h2>定制需求</h2>
<p>先选择客户类型与项目目标,系统会生成项目路径、素材建议和可交互 demo 方向。</p>
</div>
<div class="grid cols-2">
<label>客户类型
<select id="clientType">
<option>文旅局</option>
<option>政务单位</option>
<option>快消品牌</option>
<option>短剧平台</option>
</select>
</label>
<label>项目目标
<select id="projectGoal">
<option>非遗科普互动</option>
<option>政务普法活动</option>
<option>品牌联名营销</option>
<option>短剧互动改编</option>
</select>
</label>
</div>
<div class="grid cols-3">
<div class="task"><strong>方案方向</strong><p>非遗知识点拆解、互动任务、票根奖励。</p></div>
<div class="task"><strong>素材建议</strong><p>授权 IP 角色 + 地方场景 + 主题 BGM。</p></div>
<div class="task"><strong>交付形态</strong><p>H5 / 小程序 / 信息流试玩卡。</p></div>
</div>
</div>
<div class="grid cols-4" style="margin-top:14px;">
<div class="stat-card"><span class="mini">行业客户</span><b>4类</b><span class="ok">文旅/政务/品牌/短剧</span></div>
<div class="stat-card"><span class="mini">方案模板</span><b>32</b><span class="ok">可快速套用</span></div>
<div class="stat-card"><span class="mini">平均出案</span><b>15min</b><span class="warn">含素材建议</span></div>
<div class="stat-card"><span class="mini">交付入口</span><b>3</b><span class="ok">H5 / 小程序 / 信息流</span></div>
</div>
</section>
<aside class="panel pad">
<h2>定制案例池</h2>
<div class="b2b-cases" style="margin-top:12px;">
<div class="case-card"><strong>王蓝莓 × 肯德基节日联动</strong><p>品牌联名营销 / 快消品牌</p></div>
<div class="case-card"><strong>地方非遗文旅小游戏</strong><p>非遗科普互动 / 文旅局</p></div>
<div class="case-card"><strong>社区普法互动 H5</strong><p>政务普法活动 / 政务单位</p></div>
<div class="case-card"><strong>短剧互动改编番外</strong><p>短剧互动改编 / 短剧平台</p></div>
</div>
</aside>
</div>
</section>
<section class="view" id="profile">
<div class="section-head">
<div>
<h1>个人中心</h1>
<p>个人账号、消息通知、帮助与退出登录集中管理,不混入创作者数据后台。</p>
</div>
<button class="btn" data-view-jump="workshop">继续创作</button>
</div>
<div class="profile-layout">
<div class="panel pad">
<h2>账号信息</h2>
<div class="grid" style="margin-top:12px;">
<div class="stat-card"><span class="mini">当前账号</span><b>绘境创作者 1811</b><span class="ok">专业版试用中</span></div>
<div class="stat-card"><span class="mini">消息通知</span><b>12</b><span class="warn">3 条待处理</span></div>
</div>
</div>
<div class="panel pad">
<h2>个人设置</h2>
<div class="grid" style="margin-top:12px;">
<div class="setting-row"><div><strong>消息通知</strong><p>系统、素材授权、审核结果和项目协作提醒。</p></div><button class="btn secondary" data-profile-action="消息通知">查看</button></div>
<div class="setting-row"><div><strong>账号设置</strong><p>手机号、密码、登录设备和隐私偏好。</p></div><button class="btn secondary" data-profile-action="账号设置">管理</button></div>
<div class="setting-row"><div><strong>帮助中心</strong><p>教程、客服、常见问题和反馈入口。</p></div><button class="btn secondary" data-profile-action="帮助中心">打开</button></div>
<div class="setting-row"><div><strong>退出登录</strong><p>退出当前账号并清空本地会话。</p></div><button class="btn hot" data-profile-action="退出登录">退出</button></div>
</div>
</div>
</div>
</section>
</main>
</div>
<div class="modal-backdrop" id="publishModal" aria-hidden="true">
<div class="modal-card" role="dialog" aria-modal="true" aria-labelledby="publishModalTitle">
<div class="modal-head">
<div>
<h2 id="publishModalTitle">一键发布授权 IP 试玩版</h2>
<p id="publishModalDesc">选择发布渠道,自有游戏流为必选渠道,外部渠道会先标记待开通。</p>
</div>
<button class="modal-close" id="closePublishModal" aria-label="关闭发布弹窗">×</button>
</div>
<div class="publish-body">
<div class="publish-summary">
<div class="publish-metric"><span class="mini">发布版本</span><strong id="publishGameTitle">王蓝莓:经营模拟试玩版</strong></div>
<div class="publish-metric"><span class="mini">目标专区</span><strong id="publishZone">现象级IP专区 + 游戏信息流</strong></div>
<div class="publish-metric"><span class="mini">已选渠道</span><strong id="publishSelectedCount">1 / 5</strong></div>
</div>
<div class="channel-grid" id="publishChannelGrid"></div>
<label>发布备注
<textarea id="publishNote">授权锁风已通过,首发自有游戏流;外部平台渠道先标记待开通。</textarea>
</label>
<div class="publish-actions">
<button class="btn secondary" id="savePublishDraft">保存发布配置</button>
<button class="btn hot" id="confirmPublish">确认发布</button>
</div>
</div>
</div>
</div>
<div class="toast" id="toast" role="status" aria-live="polite"></div>
<script>
const $ = selector => document.querySelector(selector);
const $$ = selector => [...document.querySelectorAll(selector)];
const assetKinds = [
{
key: "sprite",
name: "图元",
icon: "▣",
short: "整套美术资源",
title: "图元模块",
desc: "一键生成统一画风的图标、贴纸、物件和收集品,不用外包也能保持风格一致。",
noteTitle: "图元风格统一生产",
noteText: "输入游戏题材与参考风格后,自动生成可用于任务、背包、奖励和关卡交互的图元包。",
chips: ["图标", "贴纸", "物件"],
prompt: "生成屋顶电台主题图元:心愿纸条、广播零件、晚会票根、任务徽章,轻科幻校园风。",
items: ["屋顶电台徽章", "心愿纸条图标", "广播零件图元", "晚会票根卡面"]
},
{
key: "role",
name: "角色",
icon: "◉",
short: "图文生成可拖拽",
title: "角色模块",
desc: "支持图片描述与文本描述生成角色,拖入输入框后智能体会按角色画风生成游戏。",
noteTitle: "角色骨骼与画风识别",
noteText: "生成后自动拆分基础动作、主体比例和配色风格,可直接拖入中间输入框作为用户附件。",
chips: ["图生角色", "文生角色", "附件识别"],
prompt: "银蓝色机甲少年,发光耳机,轻科幻街机风,适合横版动作和剧情互动。",
items: ["银蓝机甲少年", "校园广播员", "社团摄影师", "旧校服同桌"]
},
{
key: "fx",
name: "特效",
icon: "✦",
short: "技能/场景氛围",
title: "特效模块",
desc: "快速生成技能特效、场景特效和氛围粒子,支持强度、颜色与触发节奏微调。",
noteTitle: "特效套用与参数化",
noteText: "围绕玩法动作自动生成反馈光效、拖尾、点击反馈和关卡氛围,可直接挂载到节点。",
chips: ["技能", "氛围", "反馈"],
prompt: "生成校园屋顶电台修复时的电波扩散、按钮点击、任务完成和结算闪光特效。",
items: ["升级光效", "点击反馈", "技能拖尾", "氛围粒子"]
},
{
key: "scene",
name: "场景",
icon: "▤",
short: "城镇/关卡/剧情",
title: "场景模块",
desc: "快速搭建城镇、关卡、剧情界面和可交互区域,生成后可直接进入调试预览。",
noteTitle: "场景快速搭建",
noteText: "根据玩法模板生成场景层级、交互热点和镜头构图,保证角色行动与任务目标清晰。",
chips: ["关卡", "剧情", "热点"],
prompt: "生成校园屋顶、旧广播室、晚会舞台三段场景,包含可点击线索和轻解谜机关。",
items: ["校园屋顶", "年代街道", "工地任务", "蓝色实验室"]
},
{
key: "ui",
name: "界面",
icon: "▦",
short: "按钮/弹窗/状态栏",
title: "界面模块",
desc: "一站式生成按钮、弹窗、状态栏、结算页和分享卡,保证交互清晰、视觉统一。",
noteTitle: "交互界面成套生成",
noteText: "根据玩法循环自动产出主界面、任务栏、对白框、结算面板和运营位布局。",
chips: ["按钮", "弹窗", "状态栏"],
prompt: "生成剧情互动游戏 UI任务栏、对白选择、线索背包、结算页和分享卡。",
items: ["按钮套件", "弹窗组件", "状态栏", "结算页"]
},
{
key: "music",
name: "音乐",
icon: "♪",
short: "BGM/音效/环境音",
title: "音乐模块",
desc: "生成主题 BGM、按钮反馈、环境底噪和结算音效让游戏声音与画面保持同一风格。",
noteTitle: "音乐与音效编排",
noteText: "输入题材、节奏和情绪后生成循环 BGM、交互音效和场景环境音可直接写入项目。",
chips: ["BGM", "音效", "环境音"],
prompt: "生成轻科幻校园夜晚 BGM、广播电流声、按钮确认音和晚会结算欢呼音。",
items: ["主题BGM", "按钮音", "环境底噪", "结算音效"]
}
];
const taskNames = [
{ title: "图元生产", icon: "图" },
{ title: "角色骨骼", icon: "骨" },
{ title: "特效生成", icon: "效" },
{ title: "场景搭建", icon: "景" },
{ title: "界面装配", icon: "界" },
{ title: "锁风与版权", icon: "审" },
{ title: "整体游戏策划", icon: "完" }
];
const characterParts = ["头部", "左手", "右手", "躯干", "左腿", "右腿", "尾饰", "影子"];
const templateNames = ["经营模拟", "剧情互动", "解谜闯关", "TRPG跑团", "非遗科普"];
const ipList = [
{ name: "王蓝莓 IP", tone: "年代校园 / 复古生活", zone: "现象级IP专区" },
{ name: "起重集 IP", tone: "工业现场 / 团队任务", zone: "现象级IP专区" },
{ name: "小蓝 IP", tone: "轻科幻 / 萌系冒险", zone: "现象级IP专区" }
];
const packList = [
{ name: "角色原画素材", desc: "立绘、表情差分、骨骼参考", kind: "role" },
{ name: "年代场景素材", desc: "街道、店铺、剧情界面", kind: "scene" },
{ name: "IP道具素材", desc: "任务物件、收集品、奖励", kind: "prop" },
{ name: "音效BGM库", desc: "主题音乐、反馈音、环境音", kind: "sound" }
];
const publishChannels = [
{ key: "own", name: "自有游戏流", desc: "现象级 IP 专区与游戏信息流同步上线", icon: "造", required: true, state: "必选" },
{ key: "douyin", name: "抖音", desc: "短视频试玩卡与达人投放链路", icon: "抖", state: "待开通" },
{ key: "wechat", name: "微信", desc: "小程序试玩入口与社群裂变", icon: "微", state: "待开通" },
{ key: "kuaishou", name: "快手", desc: "内容流分发与直播试玩挂载", icon: "快", state: "待开通" },
{ key: "taptap", name: "TapTap", desc: "社区预约页与试玩包提审", icon: "Tap", state: "待开通" }
];
const games = {
licensed: {
title: "现象级IP专区",
rows: {
excellent: [
game("王蓝莓:复古小卖部", "经营模拟", "王蓝莓 IP", "38.2k", "licensed"),
game("小蓝:消失的零件", "解谜闯关", "小蓝 IP", "21.7k", "action"),
game("起重集:午夜吊装", "TRPG跑团", "起重集 IP", "64.9k", "licensed"),
game("王蓝莓:放学路口", "剧情互动", "王蓝莓 IP", "18.9k", "licensed")
],
new: [
game("小蓝:星轨实验室", "剧情互动", "小蓝 IP", "9.2k", "action"),
game("起重集:高空协作", "经营模拟", "起重集 IP", "12.4k", "licensed"),
game("王蓝莓:暑假作业", "解谜闯关", "王蓝莓 IP", "7.8k", "licensed"),
game("小蓝:零件大作战", "解谜闯关", "小蓝 IP", "6.1k", "action")
],
all: [
game("王蓝莓:小卖部夜班", "经营模拟", "王蓝莓 IP", "32.6k", "licensed"),
game("小蓝:蓝色能源", "非遗科普", "小蓝 IP", "14.3k", "action"),
game("起重集:任务卡组", "TRPG跑团", "起重集 IP", "19.5k", "licensed"),
game("王蓝莓:同桌计划", "剧情互动", "王蓝莓 IP", "26.8k", "licensed")
]
}
},
ugc: {
title: "UGC 孵化IP专区",
rows: {
excellent: [
game("校园奇想:屋顶电台", "剧情互动", "校园奇想档案", "28.4k", "ugc"),
game("城市怪谈:末班车", "TRPG跑团", "城市怪谈计划", "34.1k", "ugc"),
game("非遗新匠人:纸鸢试飞", "非遗科普", "非遗新匠人", "17.6k", "ugc"),
game("像素夜市:摊位升级", "经营模拟", "夜市孵化IP", "22.2k", "ugc")
],
new: [
game("玻璃海:漂流瓶", "解谜闯关", "原创世界观", "8.4k", "ugc"),
game("旧书店:午夜订单", "经营模拟", "原创角色", "6.8k", "ugc"),
game("桥洞乐队:第一首歌", "剧情互动", "音乐孵化IP", "5.9k", "ugc"),
game("木偶街区:机关盒", "解谜闯关", "非遗新匠人", "7.2k", "ugc")
],
all: [
game("校园奇想:课桌迷宫", "解谜闯关", "校园奇想档案", "20.1k", "ugc"),
game("城市怪谈:雨夜便利店", "TRPG跑团", "城市怪谈计划", "31.2k", "ugc"),
game("非遗新匠人:皮影夜游", "非遗科普", "非遗新匠人", "16.4k", "ugc"),
game("像素夜市:招牌灯", "经营模拟", "夜市孵化IP", "11.9k", "ugc")
]
}
}
};
const materialData = {
licensed: {
title: "授权 IP 素材库",
text: "包含王蓝莓 IP、起重集 IP、小蓝 IP素材带授权范围、锁风标签和商业化分成规则。",
total: "24.8k",
auth: "98%",
folders: [
{ name: "王蓝莓 IP素材", count: "8,420", tone: "年代校园 / 复古生活" },
{ name: "起重集 IP素材", count: "5,680", tone: "工业现场 / 团队任务" },
{ name: "小蓝 IP素材", count: "6,210", tone: "轻科幻 / 萌系冒险" }
]
},
ugc: {
title: "UGC 孵化 IP素材库",
text: "收录平台内有潜力的原创角色、世界观、场景和音乐,支持二次孵化与平台签约。",
total: "3.3k",
auth: "91%",
folders: [
{ name: "校园奇想档案", count: "1,260", tone: "校园幻想 / 轻剧情" },
{ name: "城市怪谈计划", count: "940", tone: "悬疑事件 / 跑团" },
{ name: "非遗新匠人", count: "1,120", tone: "传统文化 / 科普闯关" }
]
}
};
const categories = [
{ name: "角色原画素材", key: "character", desc: "立绘 / 表情 / 动作 / 骨骼参考" },
{ name: "年代场景素材", key: "scene", desc: "街道 / 店铺 / 关卡 / 剧情界面" },
{ name: "IP道具素材", key: "prop", desc: "任务物件 / 收集品 / 奖励" },
{ name: "音效BGM库", key: "sound", desc: "主题音乐 / 反馈音 / 环境音" }
];
const shelfSamples = {
character: ["主角立绘 A", "同学表情差分", "老板娘站姿", "邻居跑步动作", "限定皮肤草图", "骨骼绑定参考"],
scene: ["复古小卖部门头", "年代街道黄昏", "教室午休场景", "工地任务现场", "蓝色实验室", "结算页背景"],
prop: ["玻璃汽水", "算盘收银台", "飞行零件", "任务卡组", "贴纸奖励", "怀旧海报"],
sound: ["小卖部主题 BGM", "按钮确认音", "顾客进门铃", "技能释放音", "环境人声底噪", "结算欢呼音"]
};
const templates = [
{ name: "经营模拟", desc: "资源投入、设施升级、顾客反馈、阶段收益,适合王蓝莓年代感题材。", fit: "适配:王蓝莓 IP", steps: ["开店目标", "进货选择", "顾客事件", "收益结算", "贴纸奖励", "复玩任务"] },
{ name: "剧情互动", desc: "分支对白、角色好感、剧情 CG、隐藏结局适合粉丝向二创和 IP 番外。", fit: "适配:小蓝 IP", steps: ["开场冲突", "角色选择", "分支对白", "好感变化", "结局 CG", "同款创作"] },
{ name: "解谜闯关", desc: "线索收集、机关解锁、关卡评分、失败复活,适合轻量挑战和直播互动。", fit: "适配:小蓝 IP", steps: ["目标提示", "线索收集", "机关组合", "限时挑战", "复活广告", "排行榜"] },
{ name: "TRPG跑团", desc: "事件卡、技能判定、随机结果、多人讨论,适合起重集任务与悬疑故事。", fit: "适配:起重集 IP", steps: ["角色卡", "事件抽取", "技能判定", "失败惩罚", "团队结算", "战报分享"] },
{ name: "非遗科普", desc: "知识点拆解、互动操作、答题反馈、纪念票根,适合文旅和政企项目。", fit: "适配UGC 孵化 IP", steps: ["知识引入", "步骤互动", "问答校验", "作品展示", "票根奖励", "数据复盘"] }
];
let currentView = "home";
let currentZone = "licensed";
let currentFeed = 0;
let currentAsset = "role";
let selectedLibrary = "licensed";
let selectedFolder = "王蓝莓 IP素材";
let selectedCategory = "character";
let selectedTemplateIndex = 0;
let selectedIp = "王蓝莓 IP";
let selectedLicensedTemplate = "经营模拟";
let customAttachments = [];
let selectedPublishChannels = new Set(["own"]);
let publishContext = "licensed";
let generatedRoleIndex = 1;
let generatedAssetIndex = 1;
function game(title, template, ip, plays, cover) {
return { title, template, ip, plays, cover, finish: `${34 + Math.floor(Math.random() * 22)}%` };
}
function toast(message) {
const el = $("#toast");
el.textContent = message;
el.classList.add("show");
clearTimeout(window.toastTimer);
window.toastTimer = setTimeout(() => el.classList.remove("show"), 2200);
}
function escapeHTML(value) {
return String(value).replace(/[&<>"']/g, char => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", "\"": "&quot;", "'": "&#39;" }[char]));
}
function showView(view) {
currentView = view;
$$(".view").forEach(el => el.classList.toggle("active", el.id === view));
$$(".side-nav button").forEach(btn => btn.classList.toggle("active", btn.dataset.viewJump === view));
$("#currentLocation").textContent = {
home: "首页总览",
plaza: "游戏广场",
materials: "素材中心",
templates: "玩法模版中心",
workshop: "AI工作坊",
feed: "游戏信息流",
creator: "创作者中心",
b2b: "B端定制中心",
profile: "个人中心"
}[view] || "绘境 AI";
$$(".top-tabs button").forEach(btn => btn.classList.toggle("active", btn.dataset.topJump === view));
window.scrollTo({ top: 0, behavior: "smooth" });
}
function setTop(target) {
showView(target);
}
function renderGameRows() {
const labels = { excellent: "优秀素材案例", new: "新游推荐", all: "全部游戏" };
const zone = games[currentZone];
$("#gameRows").innerHTML = Object.entries(zone.rows).map(([key, row]) => `
<div class="game-row">
<div class="section-head" style="margin:0;">
<div><h2>${labels[key]}</h2><p>${zone.title} / ${row.length} 款可玩样例</p></div>
</div>
<div class="game-strip">${row.map(cardTemplate).join("")}</div>
</div>
`).join("");
bindGameCards();
}
function cardTemplate(item) {
return `
<button class="game-card" data-play="${item.title}">
<div class="game-cover ${item.cover}"></div>
<div class="game-body">
<div><strong>${item.title}</strong><p>${item.ip} / ${item.template}</p></div>
<div class="game-meta"><span>${item.plays} 播放</span><span>${item.finish} 完玩</span></div>
</div>
</button>
`;
}
function bindGameCards() {
$$(".game-card").forEach(card => card.addEventListener("click", () => playGame(card.dataset.play)));
}
function playGame(title) {
const all = [...games.licensed.rows.excellent, ...games.licensed.rows.new, ...games.licensed.rows.all, ...games.ugc.rows.excellent, ...games.ugc.rows.new, ...games.ugc.rows.all];
const item = all.find(gameItem => gameItem.title === title) || all[0];
const seed = [...item.title].reduce((sum, char) => sum + char.charCodeAt(0), 0);
const playLabel = item.plays.includes("k") ? item.plays.replace("k", "万") : item.plays;
$("#feedTitle").textContent = item.title;
$("#feedDesc").textContent = `${item.template} / ${item.ip},点击同款创作可进入 AI 工作坊。`;
$("#feedPlay").textContent = playLabel;
$("#feedFinish").textContent = item.finish;
$("#feedZone").textContent = item.cover === "ugc" ? "UGC孵化" : "现象级IP";
$("#feedTags").innerHTML = `<span class="chip active">${item.template}</span><span class="chip">${item.ip}</span>`;
$("#feedActionFollow").textContent = `${8 + seed % 9}.${seed % 10}`;
$("#feedActionPlay").textContent = playLabel;
$("#feedActionLike").textContent = `${2 + seed % 6}.${seed % 10}`;
$("#feedActionComment").textContent = `${3200 + seed % 6800}`;
$("#feedActionCollect").textContent = `${6100 + seed % 4200}`;
$("#feedActionShare").textContent = `${1800 + seed % 2600}`;
$("#feedActionFavorite").textContent = `${5200 + seed % 3900}`;
showView("feed");
toast(`正在试玩《${item.title}`);
}
function renderMaterials() {
const library = materialData[selectedLibrary];
$("#librarySummaryTitle").textContent = library.title;
$("#librarySummaryText").textContent = library.text;
$("#librarySummaryCount").textContent = library.total;
$("#librarySummaryAuth").textContent = library.auth;
$("#folderTitle").textContent = selectedLibrary === "licensed" ? "授权 IP 分组" : "UGC 孵化分组";
$("#folderSubtitle").textContent = selectedLibrary === "licensed" ? "点击王蓝莓、起重集、小蓝任意 IP 查看四类素材。" : "点击孵化 IP 包查看四类素材。";
if (!library.folders.some(folder => folder.name === selectedFolder)) selectedFolder = library.folders[0].name;
$("#folderGrid").innerHTML = library.folders.map(folder => `
<button class="folder-card ${folder.name === selectedFolder ? "active" : ""}" data-folder="${folder.name}">
<div class="folder-art"></div>
<div><strong>${folder.name}</strong><p>${folder.tone}</p></div>
<span class="status ${folder.name === selectedFolder ? "ok" : ""}">${folder.name === selectedFolder ? "当前" : folder.count + " 件"}</span>
</button>
`).join("");
$("#categoryGrid").innerHTML = categories.map(category => `
<button class="category-card ${category.key === selectedCategory ? "active" : ""}" data-category="${category.key}">
<div><strong>${category.name}</strong><p>${category.desc}</p></div>
<span class="status ${category.key === selectedCategory ? "ok" : ""}">${category.key === selectedCategory ? "当前" : "查看"}</span>
</button>
`).join("");
const activeCategory = categories.find(category => category.key === selectedCategory);
const shelfType = activeCategory.name.replace("素材", "").replace("库", "");
const folderLabel = selectedFolder.replace(" IP素材", "").replace("素材", "");
$("#shelfTitle").textContent = `${selectedFolder} / ${activeCategory.name}`;
$("#materialShelf").innerHTML = shelfSamples[selectedCategory].map((name, index) => `
<div class="material-card">
<div class="material-thumb ${selectedCategory === "scene" ? "scene" : selectedCategory === "prop" ? "prop" : selectedCategory === "sound" ? "sound" : ""}"></div>
<div>
<strong>${name}</strong>
<p>${shelfType} / ${folderLabel}</p>
<div class="material-meta"><span>授权清晰</span><span>风格 ${index + 1}</span></div>
<div class="material-actions"><button class="btn secondary" data-material="${name}">选用</button><button class="btn ghost" data-buy="${name}">采购</button></div>
</div>
</div>
`).join("");
$$(".library-btn").forEach(btn => btn.classList.toggle("active", btn.dataset.library === selectedLibrary));
$$("#folderGrid [data-folder]").forEach(btn => btn.addEventListener("click", () => {
selectedFolder = btn.dataset.folder;
renderMaterials();
}));
$$("#categoryGrid [data-category]").forEach(btn => btn.addEventListener("click", () => {
selectedCategory = btn.dataset.category;
renderMaterials();
}));
$$("[data-material]").forEach(btn => btn.addEventListener("click", () => toast(`已选用素材:${btn.dataset.material}`)));
$$("[data-buy]").forEach(btn => btn.addEventListener("click", () => toast(`已加入采购清单:${btn.dataset.buy}`)));
}
function renderTemplates() {
$("#templateList").innerHTML = templates.map((template, index) => `
<button class="template-card ${index === selectedTemplateIndex ? "active" : ""}" data-template-index="${index}">
<div><strong>${template.name}</strong><p>${template.desc}</p></div>
<span class="status ${index === selectedTemplateIndex ? "ok" : ""}">${index === selectedTemplateIndex ? "当前" : "套用"}</span>
</button>
`).join("");
const template = templates[selectedTemplateIndex];
$("#templateDetailTitle").textContent = template.name;
$("#templateDetailDesc").textContent = template.desc;
$("#templateFit").textContent = template.fit;
$("#templateBlueprint").innerHTML = template.steps.map((step, index) => `
<div class="blueprint-step"><span class="step-index">${index + 1}</span><div><strong>${step}</strong><p>${index < 3 ? "核心流程节点" : "商业化与复玩节点"}</p></div></div>
`).join("");
$$("#templateList [data-template-index]").forEach(btn => btn.addEventListener("click", () => {
selectedTemplateIndex = Number(btn.dataset.templateIndex);
renderTemplates();
toast(`已查看${templates[selectedTemplateIndex].name}模板`);
}));
}
function thumbClass(kindKey) {
return kindKey === "fx" ? "fx" : kindKey === "music" ? "music" : kindKey === "scene" ? "scene" : kindKey === "ui" ? "ui" : kindKey === "sprite" ? "prop" : "";
}
function activeAssetKind() {
return assetKinds.find(item => item.key === currentAsset) || assetKinds[0];
}
function addAttachment(name, type = "素材") {
if (!customAttachments.some(item => item.name === name)) customAttachments.push({ name, type });
renderAttachments();
toast(`已加入用户附件:${name}`);
}
function renderAttachments() {
const tray = $("#attachmentTray");
if (!customAttachments.length) {
tray.innerHTML = `<span class="mini">用户附件:可拖入左侧角色、图元、场景或上传图片/视频</span>`;
return;
}
tray.innerHTML = customAttachments.map(item => `
<span class="attachment-chip">${item.type}${item.name}<button class="icon-btn" style="min-height:20px;width:20px;padding:0;" data-remove-attachment="${item.name}">×</button></span>
`).join("");
$$("[data-remove-attachment]").forEach(btn => btn.addEventListener("click", event => {
event.stopPropagation();
customAttachments = customAttachments.filter(item => item.name !== btn.dataset.removeAttachment);
renderAttachments();
}));
}
function renderCharacterParts() {
$("#characterParts").innerHTML = characterParts.map((part, index) => `
<div class="part-row">
<div class="part-thumb"></div>
<div><strong>${part}</strong><p>${index < 4 ? "已绑定骨骼 / 可微调" : "自动补全 / 可替换"}</p></div>
<span class="status ${index < 4 ? "ok" : ""}">${index < 4 ? "完成" : "待调"}</span>
</div>
`).join("");
}
function renderCustomAssets() {
$("#customAssetTabs").innerHTML = assetKinds.map(kind => `
<button class="${kind.key === currentAsset ? "active" : ""}" data-asset="${kind.key}">
<span>${kind.icon}</span>
<div><strong>${kind.name}</strong><em>${kind.short}</em></div>
</button>
`).join("");
const kind = activeAssetKind();
$("#moduleToolTitle").textContent = kind.title;
$("#moduleToolDesc").textContent = kind.desc;
$("#moduleToolStatus").textContent = kind.key === "role" ? "可拖拽" : "可生成";
$("#moduleToolStatus").className = kind.key === "role" ? "status warn" : "status ok";
$("#moduleToolNote").innerHTML = `
<strong>${kind.noteTitle}</strong>
<p>${kind.noteText}</p>
<div class="chips">${kind.chips.map((chip, index) => `<span class="chip ${index === 0 ? "active" : ""}">${chip}</span>`).join("")}</div>
`;
$("[data-module-panel='role']").classList.toggle("active", kind.key === "role");
$("[data-module-panel='generic']").classList.toggle("active", kind.key !== "role");
$("#modulePromptLabel").textContent = `${kind.name}生成描述`;
$("#moduleAssetPrompt").value = kind.prompt;
$("#moduleUploadTitle").textContent = `上传${kind.name}参考`;
$("#moduleUploadText").textContent = kind.key === "music" ? "可上传视频或音频参考,提取节奏和情绪。" : "可上传图片或视频参考,提取风格、结构和动态节奏。";
$("#generateModuleAsset").textContent = `生成${kind.name}`;
$("#assetListTitle").textContent = `${kind.name}素材`;
$("#customAssetList").innerHTML = kind.items.map(name => `
<div class="asset-item generated" draggable="true" data-asset-name="${name}" data-asset-type="${kind.name}">
<div class="asset-thumb ${thumbClass(kind.key)}"></div>
<div><strong>${name}</strong><p>${kind.name === "角色" ? "可拖入输入框作为主角" : "可拖入输入框作为用户附件"}</p></div>
</div>
`).join("");
$$("#customAssetList [data-asset-name]").forEach(card => {
card.addEventListener("click", () => addAttachment(card.dataset.assetName, card.dataset.assetType));
card.addEventListener("dragstart", event => {
event.dataTransfer.setData("text/plain", JSON.stringify({ name: card.dataset.assetName, type: card.dataset.assetType }));
});
});
$$("#customAssetTabs button").forEach(btn => btn.addEventListener("click", () => {
currentAsset = btn.dataset.asset;
renderCustomAssets();
toast(`已切换到${btn.querySelector("strong").textContent}模块`);
}));
}
function generateRole() {
const roleName = currentAsset === "role" ? `生成角色${5114 + generatedRoleIndex}` : "银蓝机甲少年";
generatedRoleIndex += 1;
if (currentAsset !== "role") currentAsset = "role";
const roleKind = assetKinds.find(item => item.key === "role");
if (!roleKind.items.includes(roleName)) roleKind.items.unshift(roleName);
renderCustomAssets();
addAttachment(roleName, "角色");
$("#customStageText").textContent = `${roleName}已作为主角附件,智能体会按照该角色画风生成游戏。`;
}
function generateModuleAsset() {
const kind = activeAssetKind();
if (kind.key === "role") {
generateRole();
return;
}
const generatedName = `${kind.name}资产${generatedAssetIndex + 100}`;
generatedAssetIndex += 1;
kind.items.unshift(generatedName);
renderCustomAssets();
addAttachment(generatedName, kind.name);
$("#customStageText").textContent = `${generatedName}已加入用户附件,智能体会按当前${kind.name}风格继续生成游戏。`;
}
function taskChainMarkup(id, title, done = false) {
const progressValues = done ? [100, 100, 99, 98, 96, 94, 92] : [92, 86, 78, 66, 54, 40, 26];
return `
<div class="agent-task-chain ${done ? "complete" : ""}" id="${id}">
<div class="task-chain-head">
<div class="task-chain-title">
<span class="task-icon">${done ? "✓" : "AI"}</span>
<div>
<strong>${done ? escapeHTML(title) : "任务链正在运行"}</strong>
<p>${done ? "已写入可试玩草稿,可继续在右侧预览和微调。" : "正在按附件、画风、玩法、场景、界面、声音与调试顺序生成。"}</p>
</div>
</div>
<button class="task-chain-toggle">${done ? "完成" : "展开全部⌄"}</button>
</div>
<div class="task-chain-rows">
${taskNames.map((task, index) => `
<div class="task-chain-row">
<div class="task-step-label"><span class="task-step-icon">${task.icon}</span><strong>${task.title}</strong></div>
<div class="bar" style="--value:${progressValues[index]}%"><span></span></div>
<span>${progressValues[index]}%</span>
</div>
`).join("")}
</div>
</div>
`;
}
function renderLicensed() {
$("#licensedIpGrid").innerHTML = ipList.map(item => `
<button class="ip-card ${item.name === selectedIp ? "active" : ""}" data-ip="${item.name}">
<div><strong>${item.name}</strong><p>${item.tone}</p></div>
<span class="status ok">${item.zone}</span>
</button>
`).join("");
$("#licensedTemplateTabs").innerHTML = templateNames.map(name => `<button class="${name === selectedLicensedTemplate ? "active" : ""}" data-licensed-template="${name}">${name}</button>`).join("");
$("#licensedPackGrid").innerHTML = packList.map((item, index) => `
<button class="pack-card ${index < 2 ? "active" : ""}" data-pack="${item.name}">
<div class="pack-thumb ${item.kind === "scene" ? "scene" : item.kind === "prop" ? "prop" : item.kind === "sound" ? "sound" : ""}"></div>
<div><strong>${item.name}</strong><p>${item.desc}</p><span class="status ${index < 2 ? "ok" : ""}">${index < 2 ? "已选" : "可选"}</span></div>
</button>
`).join("");
$$("#licensedIpGrid [data-ip]").forEach(btn => btn.addEventListener("click", () => {
selectedIp = btn.dataset.ip;
$("#licensedSpeaker").textContent = selectedIp.replace(" IP", "");
renderLicensed();
toast(`已选择${selectedIp}`);
}));
$$("#licensedTemplateTabs [data-licensed-template]").forEach(btn => btn.addEventListener("click", () => {
selectedLicensedTemplate = btn.dataset.licensedTemplate;
renderLicensed();
toast(`授权 IP 流程已选择${selectedLicensedTemplate}`);
}));
$$("#licensedPackGrid [data-pack]").forEach(btn => btn.addEventListener("click", () => toast(`已检查${btn.dataset.pack}`)));
}
function renderFeedList() {
const pool = [...games.licensed.rows.excellent, ...games.ugc.rows.excellent, ...games.licensed.rows.new, ...games.ugc.rows.new];
$("#feedList").innerHTML = pool.slice(0, 7).map(item => `
<button class="task" data-play-row="${item.title}">
<strong>${item.title}</strong>
<p>${item.ip} / ${item.template} / ${item.plays} 播放</p>
</button>
`).join("");
$$("[data-play-row]").forEach(row => row.addEventListener("click", () => playGame(row.dataset.playRow)));
}
function runCustomProduction() {
const template = $("#customTemplateSelect").value;
const prompt = $("#customPrompt").value.trim() || "生成一款可试玩小游戏";
const attachmentText = customAttachments.length ? customAttachments.map(item => `${item.type}${item.name}`).join("、") : "无附件";
const title = "让子弹飞一会。。。";
const taskId = `task-chain-${Date.now()}`;
$("#agentStream").insertAdjacentHTML("beforeend", `
<div class="agent-message user">
<strong>用户请求</strong>
<p>${escapeHTML(prompt)}</p>
<div class="chips"><span class="chip active">用户附件</span><span class="chip">${escapeHTML(attachmentText)}</span></div>
</div>
${taskChainMarkup(taskId, title)}
`);
$("#agentStream").scrollTop = $("#agentStream").scrollHeight;
setTimeout(() => {
const taskCard = document.getElementById(taskId);
if (taskCard) taskCard.outerHTML = taskChainMarkup(taskId, title, true);
$("#agentStream").insertAdjacentHTML("beforeend", `
<div class="agent-task">
<div class="agent-icon">AI</div>
<div><div class="agent-result-title"><span class="agent-result-badge">完</span><strong>${escapeHTML(title)}</strong></div><p>已完成图元、骨骼、特效、场景、界面、锁风版权与整体游戏策划。</p></div>
<span class="status ok">完成</span>
</div>
`);
$("#customPreviewStatus").textContent = "可试玩";
$("#customPreviewStatus").className = "status ok";
$("#customStageText").textContent = "广播信号恢复了,拖入的角色正在屋顶电台收集第一张心愿纸条。";
$("#sideProject").textContent = title;
$("#agentStream").scrollTop = $("#agentStream").scrollHeight;
}, 720);
toast("任务已写入对话记录");
}
function runLicensedProduction() {
const title = `${selectedIp.replace(" IP", "")}${selectedLicensedTemplate}试玩版`;
$("#licensedPreviewStatus").textContent = "可发布";
$("#licensedPreviewStatus").className = "status ok";
$("#sideProject").textContent = title;
toast("授权 IP 游戏已生成将进入现象级IP专区");
}
function licensedTitle() {
return `${selectedIp.replace(" IP", "")}${selectedLicensedTemplate}试玩版`;
}
function customTitle() {
const sideTitle = $("#sideProject").textContent.trim();
if (sideTitle && sideTitle !== "王蓝莓经营模拟") return sideTitle;
return "让子弹飞一会。。。";
}
function publishConfig(context = publishContext) {
if (context === "custom") {
return {
title: customTitle(),
zone: "自有游戏流 + 游戏信息流",
heading: "一键发布自定义创作试玩版",
desc: "自定义作品默认进入自有游戏流抖音、微信、快手、TapTap 可选择并标记待开通。",
note: "自定义试玩版已完成基础生成,首发自有游戏流;外部平台渠道先标记待开通。"
};
}
const zone = $("#licensedLaunchZone").value;
return {
title: licensedTitle(),
zone,
heading: "一键发布授权 IP 试玩版",
desc: "选择发布渠道,自有游戏流为必选渠道,外部渠道会先标记待开通。",
note: `授权锁风已通过,首发${zone};外部平台渠道先标记待开通。`
};
}
function selectedPublishChannelNames() {
return publishChannels.filter(channel => selectedPublishChannels.has(channel.key)).map(channel => channel.name);
}
function renderPublishChannels() {
$("#publishChannelGrid").innerHTML = publishChannels.map(channel => {
const checked = selectedPublishChannels.has(channel.key);
const pending = !channel.required;
return `
<label class="channel-card ${checked ? "active" : ""} ${pending ? "pending" : ""}" data-publish-channel="${channel.key}">
<input type="checkbox" ${checked ? "checked" : ""} ${channel.required ? "disabled" : ""}>
<div class="channel-icon">${channel.icon}</div>
<div>
<strong>${channel.name}</strong>
<p>${channel.desc}</p>
</div>
<div class="chips">
<span class="status ${channel.required ? "ok" : "warn"}">${channel.state}</span>
<span class="channel-check">${checked ? "✓" : "+"}</span>
</div>
</label>
`;
}).join("");
$("#publishSelectedCount").textContent = `${selectedPublishChannels.size} / ${publishChannels.length}`;
$$("#publishChannelGrid [data-publish-channel]").forEach(card => {
card.addEventListener("click", event => {
const key = card.dataset.publishChannel;
const channel = publishChannels.find(item => item.key === key);
if (!channel || channel.required) return;
event.preventDefault();
if (selectedPublishChannels.has(key)) selectedPublishChannels.delete(key);
else selectedPublishChannels.add(key);
renderPublishChannels();
});
});
}
function openPublishModal(context = "licensed") {
publishContext = context;
const config = publishConfig(context);
$("#publishModalTitle").textContent = config.heading;
$("#publishModalDesc").textContent = config.desc;
$("#publishGameTitle").textContent = config.title;
$("#publishZone").textContent = config.zone;
$("#publishNote").value = config.note;
renderPublishChannels();
$("#publishModal").classList.add("show");
$("#publishModal").setAttribute("aria-hidden", "false");
}
function closePublishModal() {
$("#publishModal").classList.remove("show");
$("#publishModal").setAttribute("aria-hidden", "true");
}
function confirmPublish() {
const channelNames = selectedPublishChannelNames();
const config = publishConfig();
const statusEl = publishContext === "custom" ? $("#customPreviewStatus") : $("#licensedPreviewStatus");
statusEl.textContent = "已发布";
statusEl.className = "status ok";
$("#sideProject").textContent = config.title;
closePublishModal();
toast(`已发布到${channelNames.join("、")};外部渠道标记待开通`);
}
function sendLicensedDialog(text) {
const content = (text || $("#licensedDialogInput").value).trim();
if (!content) {
toast("请输入对白内容");
return;
}
$("#licensedDialogStream").insertAdjacentHTML("beforeend", `
<div class="dialog-bubble user">
<strong>玩家</strong>
<p>${escapeHTML(content)}</p>
</div>
<div class="dialog-bubble">
<strong>${escapeHTML(selectedIp.replace(" IP", ""))}</strong>
<p>${escapeHTML(content)} 好嘞,我来把这个分支写进试玩节点。</p>
</div>
`);
$("#licensedStageText").textContent = content;
$("#licensedDialogue").value = content;
$("#licensedDialogStatus").textContent = "已写入分支";
$("#licensedDialogStream").scrollTop = $("#licensedDialogStream").scrollHeight;
}
function nextFeed(delta) {
const pool = [...games.licensed.rows.excellent, ...games.ugc.rows.excellent, ...games.licensed.rows.new, ...games.ugc.rows.new];
currentFeed = (currentFeed + delta + pool.length) % pool.length;
playGame(pool[currentFeed].title);
}
$$(".side-nav button, [data-view-jump]").forEach(btn => btn.addEventListener("click", () => showView(btn.dataset.viewJump)));
$$(".top-tabs button").forEach(btn => btn.addEventListener("click", () => setTop(btn.dataset.topJump)));
$$(".arena-tabs button").forEach(btn => btn.addEventListener("click", () => {
currentZone = btn.dataset.zone;
$$(".arena-tabs button").forEach(item => item.classList.toggle("active", item === btn));
renderGameRows();
}));
$$(".library-btn").forEach(btn => btn.addEventListener("click", () => {
selectedLibrary = btn.dataset.library;
renderMaterials();
}));
$$("#workshopModeTabs button").forEach(btn => btn.addEventListener("click", () => {
const mode = btn.dataset.workshopMode;
$$("#workshopModeTabs button").forEach(item => item.classList.toggle("active", item === btn));
$$("[data-workshop-pane]").forEach(pane => pane.classList.toggle("active", pane.dataset.workshopPane === mode));
}));
$$("#roleGenTabs button").forEach(btn => btn.addEventListener("click", () => {
const mode = btn.dataset.roleGen;
$$("#roleGenTabs button").forEach(item => item.classList.toggle("active", item === btn));
$$("[data-role-gen-panel]").forEach(panel => panel.classList.toggle("active", panel.dataset.roleGenPanel === mode));
}));
$$("input[type=file]").forEach(input => input.addEventListener("change", event => {
toast(event.target.files[0] ? `已读取文件:${event.target.files[0].name}` : "已取消上传");
}));
$$("[data-profile-action]").forEach(btn => btn.addEventListener("click", () => toast(`${btn.dataset.profileAction}已触发`)));
$("#runCustomProduction").addEventListener("click", runCustomProduction);
$("#runLicensedProduction").addEventListener("click", runLicensedProduction);
$("#quickPlay").addEventListener("click", () => playGame($("#sideProject").textContent));
$("#licensedDialogue").addEventListener("input", event => $("#licensedStageText").textContent = event.target.value || "对白为空");
$("#customLaunchAll").addEventListener("click", () => openPublishModal("custom"));
$("#customPublishSettings").addEventListener("click", () => openPublishModal("custom"));
$("#licensedLaunchAll").addEventListener("click", () => openPublishModal("licensed"));
$("#licensedPublishSettings").addEventListener("click", () => openPublishModal("licensed"));
$("#closePublishModal").addEventListener("click", closePublishModal);
$("#publishModal").addEventListener("click", event => {
if (event.target === event.currentTarget) closePublishModal();
});
$("#savePublishDraft").addEventListener("click", () => {
closePublishModal();
toast(`${publishContext === "custom" ? "自定义创作" : "授权 IP"}发布配置已保存,自有游戏流保持必选`);
});
$("#confirmPublish").addEventListener("click", confirmPublish);
$("#licensedDialogSend").addEventListener("click", () => sendLicensedDialog());
$("#licensedDialogInput").addEventListener("keydown", event => {
if (event.key === "Enter") sendLicensedDialog();
});
$$("#licensedDialogOptions [data-dialog-option]").forEach(btn => btn.addEventListener("click", () => {
$$("#licensedDialogOptions [data-dialog-option]").forEach(item => item.classList.toggle("active", item === btn));
$("#licensedDialogInput").value = btn.dataset.dialogOption;
$("#licensedStageText").textContent = btn.dataset.dialogOption;
$("#licensedDialogue").value = btn.dataset.dialogOption;
$("#licensedDialogStatus").textContent = "分支预览中";
}));
$("#generateRoleBtn").addEventListener("click", generateRole);
$("#clearRolePrompt").addEventListener("click", () => {
$("#roleTextPrompt").value = "";
toast("角色描述已清空");
});
$("#attachFileBtn").addEventListener("click", () => $("#customFileUpload").click());
$("#customFileUpload").addEventListener("change", event => {
const file = event.target.files[0];
if (file) addAttachment(file.name, file.type.startsWith("video") ? "视频" : "图片");
});
$("#customImageUpload").addEventListener("change", event => {
const file = event.target.files[0];
if (file) addAttachment(file.name, "角色参考图");
});
$("#moduleAssetUpload").addEventListener("change", event => {
const file = event.target.files[0];
if (file) addAttachment(file.name, `${activeAssetKind().name}参考`);
});
$("#generateModuleAsset").addEventListener("click", generateModuleAsset);
$("#agentDropzone").addEventListener("dragover", event => {
event.preventDefault();
$("#agentDropzone").classList.add("dragover");
});
$("#agentDropzone").addEventListener("dragleave", () => $("#agentDropzone").classList.remove("dragover"));
$("#agentDropzone").addEventListener("drop", event => {
event.preventDefault();
$("#agentDropzone").classList.remove("dragover");
const raw = event.dataTransfer.getData("text/plain");
try {
const data = JSON.parse(raw);
addAttachment(data.name, data.type);
} catch (error) {
if (raw) addAttachment(raw, "文本");
}
});
$("#exportAnimation").addEventListener("click", () => toast("角色动作包已导出到项目草稿"));
$$(".animation-strip button").forEach(btn => btn.addEventListener("click", () => {
$$(".animation-strip button").forEach(item => item.classList.toggle("active", item === btn));
toast(`已切换动作:${btn.textContent}`);
}));
$("#prevFeed").addEventListener("click", () => nextFeed(-1));
$("#nextFeed").addEventListener("click", () => nextFeed(1));
$("#prevFeedStage").addEventListener("click", () => nextFeed(-1));
$("#nextFeedStage").addEventListener("click", () => nextFeed(1));
$("#followBtn").addEventListener("click", () => toast("已关注创作者"));
$("#playActionBtn").addEventListener("click", () => toast("已进入即玩模式"));
$("#likeBtn").addEventListener("click", () => toast("已点赞,推荐权重上升"));
$("#commentBtn").addEventListener("click", () => toast("评论面板已打开"));
$("#collectBtn").addEventListener("click", () => toast("已收藏到个人中心"));
$("#shareBtn").addEventListener("click", () => toast("分享卡已生成"));
$("#favoriteBtn").addEventListener("click", () => toast("已标记为最喜欢"));
$("#assetQuote").addEventListener("click", () => toast("已生成素材采购清单"));
$("#assetUse").addEventListener("click", () => toast("已加入项目草稿,可在工作坊读取"));
$("#templateUse").addEventListener("click", () => toast(`已应用${templates[selectedTemplateIndex].name}模板到草稿`));
$("#applyTemplateBtn").addEventListener("click", () => {
showView("workshop");
toast(`已将${templates[selectedTemplateIndex].name}模板带入工作坊`);
});
$("#favoriteTemplate").addEventListener("click", () => toast("模板已收藏"));
$("#buyTemplate").addEventListener("click", () => toast("模板已加入采购清单"));
$("#optimizeBtn").addEventListener("click", () => toast("AI 已生成一键迭代任务"));
$("#makeIteration").addEventListener("click", () => toast("改版任务已写入工作台"));
$("#submitDemand").addEventListener("click", () => {
toast(`${$("#clientType").value} / ${$("#projectGoal").value} 方案已生成`);
});
renderGameRows();
renderMaterials();
renderTemplates();
renderCustomAssets();
renderAttachments();
renderCharacterParts();
renderLicensed();
renderFeedList();
</script>
</body>
</html>