AirShelf/v1/mockups/mockup-C-step1.html
iye f420af2069
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 6s
chore: 全量推送 · 累积页面改动 + Next.js 工程骨架 + v1/ 归档 + 文档
页面 (电商AI平台/)
- account / team / settings / index / products / projects: 累积迭代
- restraint.css: 设计 token 补充
- login.html / register.html: 新增登录注册页
- _ARCHIVE.md: 归档说明

Next.js 工程骨架
- app/ + components/: 新一代 SPA 雏形 (page / layout / sidebar / topbar / GridBg / Icon)
- package.json / package-lock.json / next.config.mjs / tsconfig.json / postcss.config.mjs / next-env.d.ts

历史归档 / 文档
- v1/: 原 V1 静态稿镜像 (含 mockup-A/B/C)
- PRD.md / deployment-guide.md / _check.html
- ui参考/ / screenshots/

杂项
- .gitignore 调整
- 删除根 README.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 21:16:46 +08:00

384 lines
24 KiB
HTML
Raw Permalink 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">
<title>方案 1 · 独立 Step · 模特挑选 · 流·Studio</title>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
<link rel="stylesheet" href="../assets/restraint.css">
<style>
body { background: var(--bg); }
.demo-bar { padding: 16px 24px; background: var(--card); border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 16px; font-family: 'Inter', sans-serif; }
.demo-bar .ti { font-weight: 700; font-size: 15px; }
.demo-bar .desc { font-family: 'JetBrains Mono', monospace; font-size: 12px; color: var(--ink-3); }
/* Workbench - full screen */
.wb { height: calc(100vh - 60px); display: grid; grid-template-rows: 56px 1fr; background: var(--bg); }
/* Top bar */
.wb-top { padding: 0 24px; background: var(--card); border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 18px; }
.wb-top .ti { font-size: 15px; font-weight: 700; }
.wb-top .ti span { font-family: 'JetBrains Mono', monospace; font-size: 11px; color: var(--orange); background: var(--orange-tint); border: 1px solid var(--orange-soft); padding: 2px 6px; margin-left: 8px; letter-spacing: .04em; }
.wb-top .meta-line { font-family: 'JetBrains Mono', monospace; font-size: 11px; color: var(--ink-3); letter-spacing: .04em; }
.wb-top .right { margin-left: auto; display: flex; align-items: center; gap: 8px; }
.wb-top .x { width: 32px; height: 32px; display: grid; place-items: center; cursor: pointer; color: var(--ink-2); border: 1px solid var(--border); }
.wb-top .x:hover { color: var(--orange); border-color: var(--orange); }
/* Main split */
.wb-main { display: grid; grid-template-columns: 280px 1fr 360px; min-height: 0; }
/* Left sidebar - 5 steps */
.wb-side { border-right: 1px solid var(--border); background: var(--bg); overflow-y: auto; padding: 18px 0; }
.step-item { padding: 14px 20px; display: flex; align-items: flex-start; gap: 12px; cursor: pointer; border-left: 3px solid transparent; position: relative; }
.step-item:hover { background: var(--bg-soft); }
.step-item.active { background: var(--orange-tint); border-left-color: var(--orange); }
.step-item .num { width: 24px; height: 24px; border: 1px solid var(--border); background: var(--card); color: var(--ink-3); font-family: 'JetBrains Mono', monospace; font-size: 11px; font-weight: 700; display: grid; place-items: center; flex-shrink: 0; }
.step-item.done .num { background: var(--ink); color: #FFF; border-color: var(--ink); }
.step-item.active .num { background: var(--orange); color: #FFF; border-color: var(--orange); }
.step-item .info { flex: 1; min-width: 0; }
.step-item .ti2 { font-size: 13.5px; font-weight: 600; color: var(--ink-2); }
.step-item.active .ti2 { color: var(--ink); }
.step-item .sub { font-size: 11px; color: var(--ink-3); margin-top: 3px; font-family: 'JetBrains Mono', monospace; letter-spacing: .02em; }
.step-item.done .sub { color: var(--ink-2); font-family: 'Inter', sans-serif; letter-spacing: 0; }
.step-item.new { position: relative; }
.step-item.new::after { content: 'NEW'; position: absolute; top: 14px; right: 16px; font-family: 'JetBrains Mono', monospace; font-size: 9px; padding: 1px 5px; background: var(--orange); color: #FFF; letter-spacing: .04em; font-weight: 700; }
.side-divider { height: 1px; background: var(--border); margin: 14px 20px; }
.side-section-h { padding: 4px 20px 8px; font-family: 'JetBrains Mono', monospace; font-size: 10.5px; color: var(--ink-3); letter-spacing: .08em; text-transform: uppercase; font-weight: 600; }
/* Center canvas */
.wb-canvas { background: var(--bg); overflow-y: auto; padding: 28px 32px; display: flex; flex-direction: column; min-width: 0; }
.canvas-h { margin-bottom: 18px; display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.canvas-h h2 { font-size: 22px; font-weight: 700; letter-spacing: -.012em; }
.canvas-h p { font-size: 13px; color: var(--ink-2); margin-top: 4px; }
.canvas-h .step-tag { font-family: 'JetBrains Mono', monospace; font-size: 10.5px; color: var(--ink-3); padding: 3px 8px; background: var(--bg-soft); border: 1px solid var(--border-soft); letter-spacing: .04em; flex-shrink: 0; }
/* Search + filter toolbar */
.filter-bar { display: flex; align-items: center; gap: 10px; margin-bottom: 18px; flex-wrap: wrap; }
.search-input { position: relative; width: 280px; }
.search-input svg { position: absolute; left: 10px; top: 50%; transform: translateY(-50%); color: var(--ink-3); width: 14px; height: 14px; }
.search-input input { padding-left: 32px; height: 30px; font-size: 12.5px; background: var(--card); border: 1px solid var(--border); color: var(--ink); outline: none; width: 100%; }
.filter-chip { height: 30px; padding: 0 10px; border: 1px solid var(--border); background: var(--card); font-size: 12px; color: var(--ink-2); display: inline-flex; align-items: center; gap: 4px; cursor: pointer; font-family: inherit; }
.filter-chip:hover { background: var(--bg-soft); }
.filter-chip.active { border-color: var(--orange); color: var(--orange); background: var(--orange-tint); font-weight: 600; }
.filter-chip svg { width: 11px; height: 11px; }
.results-meta { margin-left: auto; font-family: 'JetBrains Mono', monospace; font-size: 11px; color: var(--ink-3); letter-spacing: .04em; }
/* Model grid */
.model-grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: 12px; }
@media (max-width: 1400px) { .model-grid { grid-template-columns: repeat(5, 1fr); } }
@media (max-width: 1200px) { .model-grid { grid-template-columns: repeat(4, 1fr); } }
.model-card {
aspect-ratio: 3/4;
background: var(--card);
border: 1px solid var(--border);
cursor: pointer;
position: relative;
overflow: hidden;
}
.model-card:hover { border-color: var(--ink-3); }
.model-card.selected { border: 2px solid var(--orange); }
.model-card.selected::after {
content: '✓'; position: absolute; top: 6px; right: 6px;
width: 22px; height: 22px; background: var(--orange); color: #FFF;
display: grid; place-items: center; font-weight: 700; font-size: 12px; z-index: 2;
}
.model-card .placeholder { width: 100%; height: 100%; }
.model-card .lbl-bottom {
position: absolute; bottom: 0; left: 0; right: 0;
background: rgba(255,255,255,.95); border-top: 1px solid var(--border);
padding: 6px 8px;
display: flex; flex-direction: column; gap: 2px;
}
.model-card .lbl-bottom .nm { font-size: 12px; font-weight: 600; color: var(--ink); }
.model-card .lbl-bottom .tags {
font-family: 'JetBrains Mono', monospace; font-size: 9.5px;
color: var(--ink-3); letter-spacing: .02em;
}
.model-card .pose-tag {
position: absolute; top: 6px; left: 6px;
background: rgba(0,0,0,.55); color: #FFF;
font-family: 'JetBrains Mono', monospace; font-size: 9px;
padding: 1px 5px; letter-spacing: .04em;
z-index: 1;
}
/* Right controls - hover detail */
.wb-controls { border-left: 1px solid var(--border); background: var(--bg); overflow-y: auto; padding: 22px 22px 100px; display: flex; flex-direction: column; position: relative; }
.ctrl-section { margin-bottom: 22px; }
.ctrl-section h3 { font-family: 'JetBrains Mono', monospace; font-size: 10.5px; color: var(--ink-3); letter-spacing: .08em; text-transform: uppercase; font-weight: 600; margin-bottom: 10px; }
/* Hover detail card */
.hover-detail { background: var(--card); border: 1px solid var(--border); padding: 14px; }
.hover-detail .hd-name { font-size: 15px; font-weight: 700; }
.hover-detail .hd-tags { display: flex; gap: 4px; flex-wrap: wrap; margin-top: 6px; }
.hover-detail .hd-tags span { font-family: 'JetBrains Mono', monospace; font-size: 10px; color: var(--ink-2); background: var(--bg-soft); border: 1px solid var(--border-soft); padding: 1px 5px; letter-spacing: .02em; }
.hover-detail .hd-views { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; margin-top: 12px; }
.hover-detail .hd-views .placeholder { aspect-ratio: 3/4; }
.hover-detail .hd-meta { display: flex; flex-direction: column; gap: 6px; margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border); font-size: 11.5px; color: var(--ink-2); }
.hover-detail .hd-meta div { display: flex; gap: 8px; }
.hover-detail .hd-meta .k { font-family: 'JetBrains Mono', monospace; font-size: 10.5px; color: var(--ink-3); width: 56px; letter-spacing: .04em; }
/* Selected list */
.selected-list { display: flex; flex-direction: column; gap: 6px; }
.sel-row { display: flex; align-items: center; gap: 8px; padding: 6px 8px; background: var(--card); border: 1px solid var(--border); }
.sel-row .placeholder { width: 28px; height: 36px; flex-shrink: 0; }
.sel-row .nm { flex: 1; font-size: 12px; font-weight: 600; }
.sel-row .x-btn { width: 18px; height: 18px; display: grid; place-items: center; cursor: pointer; color: var(--ink-3); }
.sel-row .x-btn:hover { color: var(--red); }
.sel-empty { padding: 14px 12px; text-align: center; font-family: 'JetBrains Mono', monospace; font-size: 11px; color: var(--ink-3); border: 1px dashed var(--border); letter-spacing: .02em; }
/* Tip */
.tip-mini { padding: 10px 12px; background: var(--orange-tint); border: 1px solid var(--orange-soft); font-size: 11.5px; color: var(--ink-2); line-height: 1.5; }
.tip-mini strong { color: var(--orange); display: block; font-family: 'JetBrains Mono', monospace; font-size: 10px; letter-spacing: .04em; margin-bottom: 4px; }
/* Bottom bar */
.wb-bottom { position: absolute; left: 0; right: 0; bottom: 0; padding: 14px 22px; background: var(--card); border-top: 1px solid var(--border); display: flex; flex-direction: column; gap: 10px; }
.wb-bottom .row1 { display: flex; align-items: center; justify-content: space-between; }
.cost-info { font-family: 'JetBrains Mono', monospace; font-size: 11px; color: var(--ink-3); letter-spacing: .04em; }
.cost-info .price { color: var(--orange); font-weight: 700; }
/* Banner: 5-step indicator */
.step-count-banner { padding: 8px 14px; background: var(--orange-tint); border: 1px solid var(--orange-soft); margin-bottom: 16px; display: flex; align-items: center; gap: 10px; font-size: 11.5px; color: var(--ink-2); }
.step-count-banner .ic { width: 16px; height: 16px; background: var(--orange); color: #FFF; display: grid; place-items: center; font-family: 'JetBrains Mono', monospace; font-size: 10px; font-weight: 700; }
</style>
</head>
<body>
<div class="demo-bar">
<a href="index.html" class="btn btn-ghost btn-sm">← 返回方案对比</a>
<span class="ti">方案 1 · 独立 Step(5 步流程)</span>
<span class="desc">// "选模特" 独立成第 3 步,canvas 充分展示模特库 · 适合 50+ 大型素材库</span>
</div>
<div class="wb">
<header class="wb-top">
<div class="ti">透真玻尿酸补水面膜 <span>[ AI 生成模式 ]</span></div>
<div class="meta-line">// 美妆个护 · ¥39.9 · 已选头图 A · WHITE-BG</div>
<div class="right">
<button class="btn btn-sm">保存草稿</button>
<div class="x"><svg width="14" height="14" viewBox="0 0 16 16"><path d="M4 4l8 8M12 4l-8 8" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg></div>
</div>
</header>
<div class="wb-main">
<!-- Left: 5 steps -->
<aside class="wb-side">
<div class="side-section-h">// CREATE FLOW · 5 STEPS</div>
<div class="step-item done"><div class="num"></div><div class="info"><div class="ti2">商品信息</div><div class="sub">名称、品类、价格、卖点</div></div></div>
<div class="step-item done"><div class="num"></div><div class="info"><div class="ti2">生成头图</div><div class="sub">已选 1 / 4 · 候选 A</div></div></div>
<div class="step-item active new"><div class="num">3</div><div class="info"><div class="ti2">挑选模特</div><div class="sub">// 50+ 模特库 · 单选/多选</div></div></div>
<div class="step-item"><div class="num">4</div><div class="info"><div class="ti2">生成上身图</div><div class="sub">// 4 选 N · 多选保留</div></div></div>
<div class="step-item"><div class="num">5</div><div class="info"><div class="ti2">完成创建</div><div class="sub">// 预览 · 提交</div></div></div>
<div class="side-divider"></div>
<div class="side-section-h">// SELECTED ASSETS</div>
<div style="padding: 0 20px;">
<div style="font-size:11.5px; color:var(--ink-3); margin-bottom:6px; font-family:'JetBrains Mono',monospace; letter-spacing:.02em;">原图 · 1 张</div>
<div class="placeholder" style="width:100%; aspect-ratio: 4/5; margin-bottom:12px;"><span class="ph-frame">补水面膜<br>1200×1500</span></div>
<div style="font-size:11.5px; color:var(--ink-3); margin-bottom:6px; font-family:'JetBrains Mono',monospace; letter-spacing:.02em;">头图 · 候选 A</div>
<div class="placeholder" style="width:100%; aspect-ratio: 1; margin-bottom:12px;"><span class="ph-frame">A · 白底简约</span></div>
<div style="font-size:11.5px; color:var(--ink-3); font-family:'JetBrains Mono',monospace; letter-spacing:.02em;">模特 · 已选 <span style="color:var(--orange); font-weight:700;" id="sel-count-side">2</span> / 50+</div>
</div>
</aside>
<!-- Center canvas: model picker -->
<main class="wb-canvas">
<div class="canvas-h">
<div>
<h2>挑选模特</h2>
<p>从 AI 模特库选 1 个或多个模特,统一白 T + 白短裤立绘。悬浮看详情和三视图。</p>
</div>
<span class="step-tag">// STEP 3 / 5 · MODEL SELECT</span>
</div>
<div class="step-count-banner">
<span class="ic">i</span>
独立成步的好处:筛选 + 搜索 + 多选都有完整空间,适合 50+ 模特库。代价是流程多一步。
</div>
<div class="filter-bar">
<div class="search-input">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="7"/><path d="m21 21-4.3-4.3"/></svg>
<input type="text" placeholder="搜索模特名称、风格…">
</div>
<button class="filter-chip active">全部 <span style="font-family:'JetBrains Mono',monospace; opacity:.7;">52</span></button>
<button class="filter-chip">女性</button>
<button class="filter-chip">男性</button>
<button class="filter-chip">25-30 岁</button>
<button class="filter-chip">都市白领</button>
<button class="filter-chip">学生</button>
<button class="filter-chip">居家</button>
<button class="filter-chip">健身</button>
<button class="filter-chip">+ 更多筛选 <svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.6"><path d="M4 6l4 4 4-4"/></svg></button>
<span class="results-meta">// 12 / 52 · 已选 <span id="sel-count" style="color:var(--orange); font-weight:700;">2</span></span>
</div>
<div class="model-grid" id="model-grid">
<div class="model-card selected" data-id="m1" onmouseenter="hoverModel('林夕','女 · 25-30','都市白领',['温柔','日常','OL','通勤'])">
<span class="pose-tag">[ 立绘 · 肩上 ]</span>
<div class="placeholder"><span class="ph-frame">林夕 · 都市女</span></div>
<div class="lbl-bottom"><div class="nm">林夕</div><div class="tags">女 · 25-30 · 都市白领</div></div>
</div>
<div class="model-card" data-id="m2" onmouseenter="hoverModel('阿楠','女 · 25-30','姐妹/同事',['精致','干练','短发'])">
<span class="pose-tag">[ 立绘 · 肩上 ]</span>
<div class="placeholder"><span class="ph-frame">阿楠</span></div>
<div class="lbl-bottom"><div class="nm">阿楠</div><div class="tags">女 · 25-30 · 同事</div></div>
</div>
<div class="model-card selected" data-id="m3" onmouseenter="hoverModel('小七','女 · 18-22','学生/Z世代',['青春','元气','校园'])">
<span class="pose-tag">[ 立绘 · 肩上 ]</span>
<div class="placeholder"><span class="ph-frame">小七 · 学生</span></div>
<div class="lbl-bottom"><div class="nm">小七</div><div class="tags">女 · 18-22 · 学生</div></div>
</div>
<div class="model-card" data-id="m4" onmouseenter="hoverModel('王姐','女 · 38-45','妈妈/居家',['亲和','成熟','温暖'])">
<span class="pose-tag">[ 立绘 · 肩上 ]</span>
<div class="placeholder"><span class="ph-frame">王姐 · 居家</span></div>
<div class="lbl-bottom"><div class="nm">王姐</div><div class="tags">女 · 38-45 · 妈妈</div></div>
</div>
<div class="model-card" data-id="m5" onmouseenter="hoverModel('阿杰','男 · 28-35','通勤男',['商务','干练','西装'])">
<span class="pose-tag">[ 立绘 · 肩上 ]</span>
<div class="placeholder"><span class="ph-frame">阿杰 · 通勤男</span></div>
<div class="lbl-bottom"><div class="nm">阿杰</div><div class="tags">男 · 28-35 · 通勤</div></div>
</div>
<div class="model-card" data-id="m6" onmouseenter="hoverModel('阿强','男 · 22-28','健身男',['阳光','运动','肌肉'])">
<span class="pose-tag">[ 立绘 · 肩上 ]</span>
<div class="placeholder"><span class="ph-frame">阿强 · 健身男</span></div>
<div class="lbl-bottom"><div class="nm">阿强</div><div class="tags">男 · 22-28 · 健身</div></div>
</div>
<div class="model-card" data-id="m7" onmouseenter="hoverModel('小苏','女 · 22-26','文艺研究生',['书卷气','静谧','文艺'])">
<span class="pose-tag">[ 立绘 · 肩上 ]</span>
<div class="placeholder"><span class="ph-frame">小苏 · 文艺女</span></div>
<div class="lbl-bottom"><div class="nm">小苏</div><div class="tags">女 · 22-26 · 文艺</div></div>
</div>
<div class="model-card" data-id="m8" onmouseenter="hoverModel('文文','女 · 30-38','母亲',['温柔','母性','温暖'])">
<span class="pose-tag">[ 立绘 · 肩上 ]</span>
<div class="placeholder"><span class="ph-frame">文文 · 母亲</span></div>
<div class="lbl-bottom"><div class="nm">文文</div><div class="tags">女 · 30-38 · 母亲</div></div>
</div>
<div class="model-card" data-id="m9" onmouseenter="hoverModel('老王','男 · 45-55','大叔',['沉稳','成熟','商务'])">
<span class="pose-tag">[ 立绘 · 肩上 ]</span>
<div class="placeholder"><span class="ph-frame">老王 · 大叔</span></div>
<div class="lbl-bottom"><div class="nm">老王</div><div class="tags">男 · 45-55 · 大叔</div></div>
</div>
<div class="model-card" data-id="m10" onmouseenter="hoverModel('萌萌','女 · 18-22','Z世代',['可爱','潮流','二次元'])">
<span class="pose-tag">[ 立绘 · 肩上 ]</span>
<div class="placeholder"><span class="ph-frame">萌萌 · Z世代</span></div>
<div class="lbl-bottom"><div class="nm">萌萌</div><div class="tags">女 · 18-22 · Z 世代</div></div>
</div>
<div class="model-card" data-id="m11" onmouseenter="hoverModel('Leo','男 · 30-38','健身教练',['专业','力量','健身房'])">
<span class="pose-tag">[ 立绘 · 肩上 ]</span>
<div class="placeholder"><span class="ph-frame">Leo · 教练</span></div>
<div class="lbl-bottom"><div class="nm">Leo</div><div class="tags">男 · 30-38 · 教练</div></div>
</div>
<div class="model-card" data-id="m12" onmouseenter="hoverModel('双人组合','双人 · 25-30','闺蜜',['亲密','日常','搭档'])">
<span class="pose-tag">[ 立绘 · 双人 ]</span>
<div class="placeholder"><span class="ph-frame">闺蜜双人</span></div>
<div class="lbl-bottom"><div class="nm">闺蜜组合</div><div class="tags">双人 · 25-30</div></div>
</div>
</div>
<div style="margin-top: 18px; padding: 12px 16px; background: var(--card); border: 1px dashed var(--border); text-align: center; font-family: 'JetBrains Mono', monospace; font-size: 11.5px; color: var(--ink-3); letter-spacing: .02em;">
// 还有 40 个模特 · 滚动加载 / 用上方筛选缩小范围
</div>
</main>
<!-- Right: hover detail + selected list -->
<aside class="wb-controls">
<div class="ctrl-section">
<h3>// 当前悬浮 · DETAIL</h3>
<div class="hover-detail" id="hover-detail">
<div class="hd-name">林夕</div>
<div class="hd-tags">
<span></span><span>25-30</span><span>都市白领</span><span>温柔</span><span>OL</span><span>通勤</span>
</div>
<div class="hd-views">
<div class="placeholder"><span class="ph-frame">正面</span></div>
<div class="placeholder"><span class="ph-frame">侧面</span></div>
<div class="placeholder"><span class="ph-frame">背面</span></div>
</div>
<div class="hd-meta">
<div><span class="k">// 服装</span><span>白 T + 白短裤(默认立绘)</span></div>
<div><span class="k">// 年龄</span><span>25-30 岁 · 可微调 ±3</span></div>
<div><span class="k">// 身材</span><span>普通女 · 165cm / 50kg</span></div>
<div><span class="k">// 用过</span><span>4 个项目 · 平均评分 4.5</span></div>
</div>
</div>
</div>
<div class="ctrl-section">
<h3>// 已选模特 · <span style="color:var(--orange); font-weight:700;" id="sel-count-3">2</span></h3>
<div class="selected-list" id="selected-list">
<div class="sel-row" data-id="m1">
<div class="placeholder"><span class="ph-frame"></span></div>
<div class="nm">林夕 · 都市白领</div>
<div class="x-btn" title="移除"></div>
</div>
<div class="sel-row" data-id="m3">
<div class="placeholder"><span class="ph-frame"></span></div>
<div class="nm">小七 · 学生</div>
<div class="x-btn" title="移除"></div>
</div>
</div>
</div>
<div class="ctrl-section">
<h3>// TIP</h3>
<div class="tip-mini">
<strong>多选会怎样?</strong>
每选一个模特,下一步会为其各自生成 4 张上身图。已选 2 个 = 8 张候选,可多选保留。
</div>
</div>
<div class="wb-bottom">
<div class="row1">
<span class="cost-info">// 预计 <span class="price">¥0.80</span> / 8 张</span>
<span class="cost-info">3 / 5</span>
</div>
<div class="hstack">
<button class="btn" style="flex:1;">← 上一步</button>
<button class="btn btn-primary" style="flex:1;">下一步 → 生成上身图</button>
</div>
</div>
</aside>
</div>
</div>
<script>
// multi select
document.querySelectorAll('.model-card').forEach(c => {
c.onclick = () => {
c.classList.toggle('selected');
updateCount();
};
});
function updateCount() {
const n = document.querySelectorAll('.model-card.selected').length;
document.getElementById('sel-count').textContent = n;
document.getElementById('sel-count-3').textContent = n;
document.getElementById('sel-count-side').textContent = n;
}
function hoverModel(name, base, role, tags) {
const hd = document.getElementById('hover-detail');
hd.querySelector('.hd-name').textContent = name;
hd.querySelector('.hd-tags').innerHTML = (base.split(' · ')).concat([role]).concat(tags).map(t => `<span>${t}</span>`).join('');
}
document.querySelectorAll('.x-btn').forEach(b => {
b.onclick = (e) => {
e.stopPropagation();
const row = b.closest('.sel-row');
const id = row.dataset.id;
document.querySelector(`.model-card[data-id="${id}"]`)?.classList.remove('selected');
row.remove();
updateCount();
};
});
</script>
</body>
</html>