diff --git a/core/frontend/src/ai-tools-page.css b/core/frontend/src/ai-tools-page.css index c0eb4a1..7f6fc5a 100644 --- a/core/frontend/src/ai-tools-page.css +++ b/core/frontend/src/ai-tools-page.css @@ -978,3 +978,518 @@ .image-workbench .ic-param-menu .mi.selected { color: var(--heat); font-weight: 600; } .image-workbench .ic-param-menu .mi .mi-check { margin-left: auto; opacity: 0; color: var(--heat); } .image-workbench .ic-param-menu .mi.selected .mi-check { opacity: 1; } + +/* ============================================================ + C · 模特图方案对比 Demo(.model-demo · 纯静态展示) + 基线:public/exact/model-photo-demo-a.html(参数面板 + 结果双栏) + public/exact/model-photo-demo-b.html(任务流 + 底部 fixed 参数栏) + 逐字对齐 .content 级正文。全局 token + 共享 .pill;.content padding 抵消同 .image-workbench。 + ============================================================ */ +.model-demo { + /* 抵消 .content 的 36/48/60 padding,贴边铺满(同 .image-workbench 思路) */ + margin: -36px -48px -60px; + height: calc(100vh - 65px); + display: flex; flex-direction: column; + background: var(--background-base); + overflow: hidden; +} + +/* 顶部 demo 提示条(两版共用) */ +.model-demo .dm-banner { + flex-shrink: 0; + margin: 12px 28px 0; + padding: 8px 12px; + background: var(--heat-12); + border: 1px dashed var(--heat-20); + border-radius: var(--r-sm); + font-size: 12px; color: var(--accent-black); + font-family: var(--font-mono); letter-spacing: .02em; line-height: 1.5; +} +.model-demo .dm-banner b { color: var(--heat); } + +/* 两栏:左侧栏 260px + 主区 */ +.model-demo .dm-grid { + flex: 1; min-height: 0; + display: grid; + grid-template-columns: 260px minmax(0, 1fr); +} +@media (max-width: 1100px) { + .model-demo .dm-grid { grid-template-columns: 220px minmax(0, 1fr); } +} + +/* ── 左侧栏 · 商品空间(两版共用) ── */ +.model-demo .dm-side { + border-right: 1px solid var(--border-faint); + background: var(--surface); + display: flex; flex-direction: column; + min-height: 0; +} +.model-demo .dm-side-h { padding: 14px 14px 10px; flex-shrink: 0; } +.model-demo .dm-side-h .ti-row { display: flex; align-items: center; margin-bottom: 10px; } +.model-demo .dm-side-h .ti { + font-size: 11px; font-family: var(--font-mono); + color: var(--black-alpha-48); letter-spacing: .08em; text-transform: uppercase; +} +.model-demo .dm-side-h .add { + margin-left: auto; + width: 22px; height: 22px; + display: grid; place-items: center; + background: var(--heat-12); color: var(--heat); + border: 0; border-radius: var(--r-sm); + cursor: pointer; +} +.model-demo .dm-side-h .add svg { width: 11px; height: 11px; } + +.model-demo .dm-search { + display: flex; align-items: center; gap: 8px; + height: 32px; padding: 0 10px; + background: var(--background-lighter); + border: 1px solid var(--border-faint); + border-radius: var(--r-sm); + transition: border-color var(--t-base), background var(--t-base); +} +.model-demo .dm-search:focus-within { border-color: var(--heat-40); background: var(--surface); } +.model-demo .dm-search svg { width: 13px; height: 13px; color: var(--black-alpha-48); flex-shrink: 0; } +.model-demo .dm-search input { + flex: 1; min-width: 0; height: 100%; + border: 0; outline: 0; background: transparent; + font-size: 12.5px; color: var(--accent-black); font-family: inherit; +} +.model-demo .dm-search input::placeholder { color: var(--black-alpha-48); } + +.model-demo .dm-prod-list { + flex: 1; min-height: 0; + overflow-y: auto; + padding: 4px 10px 10px; + display: flex; flex-direction: column; gap: 4px; +} +.model-demo .dm-prod { + display: flex; align-items: center; gap: 10px; + padding: 8px; + border: 1px solid transparent; + border-radius: var(--r-sm); + cursor: pointer; text-align: left; + background: transparent; font-family: inherit; + transition: background var(--t-base), border-color var(--t-base); +} +.model-demo .dm-prod:hover { background: var(--background-lighter); } +.model-demo .dm-prod.active { background: var(--heat-12); border-color: var(--heat-20); } +.model-demo .dm-prod .thumb { + flex-shrink: 0; + width: 40px; height: 40px; + border: 1px solid var(--border-faint); + border-radius: var(--r-sm); + overflow: hidden; + background: repeating-linear-gradient(135deg, transparent 0 4px, var(--black-alpha-4) 4px 5px); + display: grid; place-items: center; + font-family: var(--font-mono); font-size: 9px; color: var(--black-alpha-32); +} +.model-demo .dm-prod.active .thumb { border-color: var(--heat); } +.model-demo .dm-prod .body { flex: 1; min-width: 0; } +.model-demo .dm-prod .nm { + font-size: 12.5px; color: var(--accent-black); font-weight: 500; line-height: 1.3; + white-space: nowrap; overflow: hidden; text-overflow: ellipsis; +} +.model-demo .dm-prod.active .nm { color: var(--heat); font-weight: 600; } +.model-demo .dm-prod .sub { + margin-top: 2px; + font-family: var(--font-mono); font-size: 10px; + color: var(--black-alpha-48); letter-spacing: .02em; + white-space: nowrap; overflow: hidden; text-overflow: ellipsis; +} + +.model-demo .dm-all { + flex-shrink: 0; + margin: 0 10px 12px; + padding: 10px 12px; + background: var(--background-lighter); + border: 1px dashed var(--border-faint); + border-radius: var(--r-sm); + color: var(--black-alpha-72); + font-size: 12px; font-family: inherit; cursor: pointer; + display: flex; align-items: center; gap: 6px; + transition: border-color var(--t-base), color var(--t-base), background var(--t-base); +} +.model-demo .dm-all:hover { border-color: var(--heat); color: var(--heat); background: var(--heat-12); } +.model-demo .dm-all .ct { + color: var(--black-alpha-48); + font-family: var(--font-mono); font-size: 10.5px; + margin-left: auto; +} +.model-demo .dm-all svg { width: 12px; height: 12px; } +.model-demo .dm-all .arrow { margin-left: 4px; } + +/* 主区 · 返回 pill(基线无,挂主区头部,保留 onBack) */ +.model-demo .dm-back { + flex-shrink: 0; + display: inline-flex; align-items: center; gap: 6px; + height: 30px; padding: 0 12px 0 10px; + background: var(--surface); + border: 1px solid var(--border-faint); + border-radius: var(--r-pill); + color: var(--accent-black); + font-size: 12.5px; font-weight: 500; font-family: inherit; + cursor: pointer; + transition: background var(--t-base), border-color var(--t-base), color var(--t-base); +} +.model-demo .dm-back:hover { background: var(--black-alpha-4); border-color: var(--black-alpha-24); } +.model-demo .dm-back svg { width: 14px; height: 14px; } + +/* ── 主区(两版共用骨架) ── */ +.model-demo .dm-main { + display: flex; flex-direction: column; + min-height: 0; overflow: hidden; + position: relative; +} + +/* 批次卡(两版共用) */ +.model-demo .dm-batch { + background: var(--surface); + border: 1px solid var(--border-faint); + border-radius: var(--r-md); + padding: 14px 16px; + margin-bottom: 14px; +} +.model-demo .dm-batch-h .pic { + flex-shrink: 0; + width: 28px; height: 28px; + background: var(--background-lighter); + border: 1px solid var(--border-faint); + border-radius: var(--r-sm); + display: grid; place-items: center; + color: var(--heat); + font-family: var(--font-mono); font-size: 11px; font-weight: 600; +} +.model-demo .dm-batch-h .meta { flex: 1; min-width: 0; } +.model-demo .dm-batch-h .nm { font-size: 13px; font-weight: 600; color: var(--accent-black); } +.model-demo .dm-batch-h .info { margin-top: 2px; font-family: var(--font-mono); font-size: 10.5px; color: var(--black-alpha-48); letter-spacing: .02em; } +.model-demo .dm-batch-h .info .sep { color: var(--black-alpha-24); } +.model-demo .dm-batch-h .ops { display: flex; gap: 4px; } +.model-demo .dm-batch-h .ops button { + width: 28px; height: 28px; + background: var(--surface); + border: 1px solid var(--border-faint); + border-radius: var(--r-sm); + color: var(--black-alpha-56); cursor: pointer; + display: grid; place-items: center; + transition: border-color var(--t-base), color var(--t-base); +} +.model-demo .dm-batch-h .ops button:hover { border-color: var(--heat-20); color: var(--heat); } +.model-demo .dm-batch-h .ops button svg { width: 13px; height: 13px; } + +.model-demo .dm-batch-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; } +@media (max-width: 1400px) { .model-demo .dm-batch-grid { grid-template-columns: repeat(3, 1fr); } } +.model-demo .dm-cell { + aspect-ratio: 3 / 4; + background: var(--background-lighter); + border: 1px solid var(--border-faint); + border-radius: var(--r-sm); + overflow: hidden; position: relative; cursor: pointer; +} +.model-demo .dm-cell .ph { + position: absolute; inset: 0; + display: grid; place-items: center; + font-family: var(--font-mono); font-size: 11px; color: var(--black-alpha-32); + background: repeating-linear-gradient(135deg, transparent 0 6px, var(--black-alpha-3) 6px 7px); +} +.model-demo .dm-cell .tag { + position: absolute; top: 6px; left: 6px; + padding: 2px 6px; + background: var(--accent-black); + color: var(--accent-white); + border-radius: var(--r-sm); + font-size: 10px; font-weight: 500; +} + +/* ════════════════════════════════════════════════ + 方案 A · 参数面板 + 结果双栏 + ════════════════════════════════════════════════ */ +.model-demo.dm-a .dm-main-h { + flex-shrink: 0; + display: flex; align-items: center; gap: 14px; + padding: 14px 28px; + border-bottom: 1px solid var(--border-faint); + background: var(--surface); +} +.model-demo.dm-a .dm-main-h .cur { min-width: 0; } +.model-demo.dm-a .dm-main-h .crumb { + font-family: var(--font-mono); font-size: 10.5px; + color: var(--black-alpha-48); letter-spacing: .04em; +} +.model-demo.dm-a .dm-main-h h2 { + font-size: 20px; font-weight: 600; + letter-spacing: -.015em; color: var(--accent-black); +} +.model-demo.dm-a .dm-main-h .stats { + margin-left: auto; + display: flex; gap: 6px; + font-family: var(--font-mono); font-size: 11px; + color: var(--black-alpha-48); letter-spacing: .02em; +} +.model-demo.dm-a .dm-main-h .stats b { color: var(--accent-black); font-weight: 600; } +.model-demo.dm-a .dm-main-h .stats .sep { color: var(--black-alpha-24); } + +.model-demo.dm-a .dm-body { + flex: 1; min-height: 0; + display: grid; grid-template-columns: 320px minmax(0, 1fr); +} +@media (max-width: 1100px) { .model-demo.dm-a .dm-body { grid-template-columns: 280px minmax(0, 1fr); } } + +/* 左侧参数面板 */ +.model-demo.dm-a .dm-form { + border-right: 1px solid var(--border-faint); + background: var(--surface); + display: flex; flex-direction: column; + min-height: 0; +} +.model-demo.dm-a .dm-form-scroll { flex: 1; min-height: 0; overflow-y: auto; padding: 16px 18px; } +.model-demo.dm-a .dm-field { margin-bottom: 16px; } +.model-demo.dm-a .dm-field:last-child { margin-bottom: 0; } +.model-demo.dm-a .dm-field-h { font-size: 12px; font-weight: 600; color: var(--accent-black); margin-bottom: 8px; } +.model-demo.dm-a .dm-field-h .opt { font-weight: 400; font-size: 11px; color: var(--black-alpha-48); margin-left: 4px; } + +.model-demo.dm-a .dm-models { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; } +.model-demo.dm-a .dm-model { + aspect-ratio: 3 / 4; + border: 1px solid var(--border-faint); + background: var(--background-lighter); + border-radius: var(--r-sm); + position: relative; cursor: pointer; overflow: hidden; + transition: border-color var(--t-base); +} +.model-demo.dm-a .dm-model:hover { border-color: var(--black-alpha-32); } +.model-demo.dm-a .dm-model.selected { border-color: var(--heat); border-width: 2px; } +.model-demo.dm-a .dm-model .ph { + position: absolute; inset: 0; + display: grid; place-items: center; + font-family: var(--font-mono); font-size: 10px; color: var(--black-alpha-32); + background: repeating-linear-gradient(135deg, transparent 0 6px, var(--black-alpha-3) 6px 7px); +} +.model-demo.dm-a .dm-model .nm { + position: absolute; bottom: 0; left: 0; right: 0; + padding: 4px 6px; + background: linear-gradient(transparent, var(--black-alpha-48)); + font-size: 10px; color: var(--accent-white); font-weight: 500; +} +.model-demo.dm-a .dm-model.selected::after { + content: ''; position: absolute; top: 4px; right: 4px; + width: 14px; height: 14px; + background: var(--heat) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E") no-repeat center / 9px; + border-radius: 50%; +} +.model-demo.dm-a .dm-model.add { + border-style: dashed; + display: flex; align-items: center; justify-content: center; + color: var(--black-alpha-48); +} + +.model-demo.dm-a .dm-chip-row { display: flex; flex-wrap: wrap; gap: 6px; } +.model-demo.dm-a .dm-chip { + display: inline-flex; align-items: center; + height: 28px; padding: 0 11px; + background: var(--surface); + border: 1px solid var(--border-faint); + border-radius: var(--r-sm); + font-size: 12px; color: var(--black-alpha-72); + font-family: inherit; cursor: pointer; + transition: border-color var(--t-base), color var(--t-base), background var(--t-base); +} +.model-demo.dm-a .dm-chip:hover { border-color: var(--black-alpha-32); color: var(--accent-black); } +.model-demo.dm-a .dm-chip.active { background: var(--heat-12); color: var(--heat); border-color: var(--heat-20); font-weight: 600; } + +.model-demo.dm-a .dm-textarea { + width: 100%; min-height: 60px; + padding: 8px 10px; + background: var(--background-lighter); + border: 1px solid var(--black-alpha-12); + border-radius: var(--r-sm); + font-family: inherit; font-size: 12.5px; + color: var(--accent-black); + outline: none; resize: vertical; +} +.model-demo.dm-a .dm-textarea::placeholder { color: var(--black-alpha-48); } +.model-demo.dm-a .dm-textarea:focus { border-color: var(--heat-40); background: var(--surface); } + +.model-demo.dm-a .dm-form-cta { + flex-shrink: 0; + padding: 14px 18px; + border-top: 1px solid var(--border-faint); + background: var(--surface); +} +.model-demo.dm-a .dm-cost { + display: flex; align-items: center; justify-content: space-between; + margin-bottom: 10px; + font-family: var(--font-mono); font-size: 11px; + color: var(--black-alpha-48); letter-spacing: .02em; +} +.model-demo.dm-a .dm-cost .v { color: var(--accent-black); font-weight: 600; } +.model-demo.dm-a .dm-gen { + width: 100%; height: 42px; + background: var(--heat); color: var(--accent-white); + border: 1px solid var(--heat); border-radius: var(--r-md); + font-size: 14px; font-weight: 600; font-family: inherit; + cursor: pointer; + display: inline-flex; align-items: center; justify-content: center; gap: 8px; + box-shadow: var(--shadow-cta); +} +.model-demo.dm-a .dm-gen svg { width: 15px; height: 15px; } + +/* 右侧结果区 */ +.model-demo.dm-a .dm-result { + background: var(--background-base); + min-height: 0; overflow-y: auto; + padding: 22px 24px; +} +.model-demo.dm-a .dm-result-h { display: flex; align-items: baseline; gap: 10px; margin-bottom: 14px; } +.model-demo.dm-a .dm-result-h .ti { font-size: 15px; font-weight: 600; color: var(--accent-black); } +.model-demo.dm-a .dm-result-h .sub { font-family: var(--font-mono); font-size: 10.5px; color: var(--black-alpha-48); letter-spacing: .02em; } +.model-demo.dm-a .dm-batch-h { + display: flex; align-items: center; gap: 10px; + margin-bottom: 12px; padding-bottom: 10px; + border-bottom: 1px solid var(--border-faint); +} + +/* ════════════════════════════════════════════════ + 方案 B · v2:任务流主区 + 底部 fixed 参数栏 + ════════════════════════════════════════════════ */ +.model-demo.dm-b .dm-main-h { + flex-shrink: 0; + padding: 16px 28px 12px; + border-bottom: 1px solid var(--border-faint); + background: var(--surface); +} +.model-demo.dm-b .dm-main-h .crumb { + font-family: var(--font-mono); font-size: 10.5px; + color: var(--black-alpha-48); letter-spacing: .04em; margin-bottom: 4px; +} +.model-demo.dm-b .dm-main-h .title-row { display: flex; align-items: center; gap: 14px; } +.model-demo.dm-b .dm-main-h h2 { + font-size: 22px; font-weight: 600; + letter-spacing: -.015em; color: var(--accent-black); +} +.model-demo.dm-b .dm-main-h .title-row .dm-back { margin-left: auto; } +.model-demo.dm-b .dm-main-h .row { display: flex; align-items: center; gap: 16px; margin-top: 6px; } +.model-demo.dm-b .dm-main-h .stats { + font-family: var(--font-mono); font-size: 11px; + color: var(--black-alpha-48); letter-spacing: .02em; + display: flex; gap: 4px; +} +.model-demo.dm-b .dm-main-h .stats b { color: var(--accent-black); font-weight: 600; } +.model-demo.dm-b .dm-main-h .stats .sep { color: var(--black-alpha-24); } +.model-demo.dm-b .dm-main-h .spacer { flex: 1; } + +.model-demo.dm-b .dm-tb { display: flex; gap: 8px; align-items: center; } +.model-demo.dm-b .dm-tb .icbtn { + width: 30px; height: 30px; + background: var(--surface); + border: 1px solid var(--border-faint); + border-radius: var(--r-sm); + color: var(--black-alpha-72); + cursor: pointer; display: grid; place-items: center; + transition: border-color var(--t-base), color var(--t-base); +} +.model-demo.dm-b .dm-tb .icbtn:hover { border-color: var(--heat-20); color: var(--heat); } +.model-demo.dm-b .dm-tb .icbtn svg { width: 13px; height: 13px; } +.model-demo.dm-b .dm-tb .chip { + display: inline-flex; align-items: center; gap: 6px; + height: 30px; padding: 0 10px; + background: var(--surface); + border: 1px solid var(--border-faint); + border-radius: var(--r-sm); + font-size: 12px; color: var(--black-alpha-72); + font-family: inherit; cursor: pointer; + transition: border-color var(--t-base), color var(--t-base); +} +.model-demo.dm-b .dm-tb .chip:hover { border-color: var(--heat-20); color: var(--heat); } +.model-demo.dm-b .dm-tb .chip svg { width: 10px; height: 10px; opacity: .6; } + +.model-demo.dm-b .dm-stream { + flex: 1; min-height: 0; + overflow-y: auto; + padding: 22px 28px 200px; + background: var(--background-base); +} +.model-demo.dm-b .dm-day-h { + display: flex; align-items: baseline; gap: 8px; + margin: 6px 0 10px; + font-family: var(--font-mono); font-size: 10.5px; + color: var(--black-alpha-48); letter-spacing: .06em; text-transform: uppercase; +} +.model-demo.dm-b .dm-day-h::before { + content: ''; width: 14px; height: 1px; + background: var(--black-alpha-24); + display: inline-block; margin-right: 2px; +} +.model-demo.dm-b .dm-day-h .ct { + color: var(--black-alpha-72); font-weight: 500; + margin-left: auto; text-transform: none; letter-spacing: 0; +} + +.model-demo.dm-b .dm-batch-h { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; } +.model-demo.dm-b .dm-batch-h .nm { font-size: 13.5px; } +.model-demo.dm-b .dm-batch-h .info { display: flex; flex-wrap: wrap; gap: 4px; } +/* 状态 pill 紧贴标题右侧(局部尺寸变体 · 不改全局 .pill) */ +.model-demo.dm-b .stat-pill { + margin-left: 8px; + padding: 2px 7px; + font-size: 10px; +} +.model-demo.dm-b .stat-pill .dot { width: 4px; height: 4px; } + +.model-demo.dm-b .dm-cell.gen .ph { animation: dm-pulse 1.4s ease-in-out infinite; } +@keyframes dm-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .55; } } +.model-demo.dm-b .dm-cell.err { border-color: var(--accent-crimson); } +.model-demo.dm-b .dm-cell.err .ph { color: var(--accent-crimson); background: var(--crimson-bg); } + +/* 底部 fixed 参数面板 */ +.model-demo.dm-b .dm-param-wrap { + position: absolute; left: 0; right: 0; bottom: 0; + padding: 14px 28px 22px; + background: linear-gradient(to bottom, transparent 0, var(--background-base) 24px); + z-index: 5; +} +.model-demo.dm-b .dm-param { + max-width: 1180px; margin: 0 auto; + background: var(--surface); + border: 1px solid var(--border-faint); + border-radius: var(--r-md); + padding: 10px 14px; + display: flex; align-items: center; gap: 10px; + box-shadow: var(--shadow-floating); +} +.model-demo.dm-b .dm-param .pchip { + display: inline-flex; align-items: center; gap: 6px; + height: 30px; padding: 0 12px; + background: var(--background-lighter); + border: 1px solid transparent; + border-radius: var(--r-pill); + font-size: 12px; color: var(--black-alpha-72); + cursor: pointer; font-family: inherit; + transition: border-color var(--t-base), background var(--t-base), color var(--t-base); +} +.model-demo.dm-b .dm-param .pchip:hover { background: var(--surface); border-color: var(--border-faint); } +.model-demo.dm-b .dm-param .pchip.active { background: var(--heat-12); color: var(--heat); } +.model-demo.dm-b .dm-param .pchip svg { width: 10px; height: 10px; opacity: .6; } +.model-demo.dm-b .dm-param .pchip .lbl-mono { + font-family: var(--font-mono); font-size: 10px; + color: var(--black-alpha-48); letter-spacing: .02em; +} +.model-demo.dm-b .dm-param .pchip.active .lbl-mono { color: var(--heat); } +.model-demo.dm-b .dm-param .pchip .muted { color: var(--black-alpha-48); } +.model-demo.dm-b .dm-param .spacer { flex: 1; } +.model-demo.dm-b .dm-param .meta-right { + font-family: var(--font-mono); font-size: 10.5px; + color: var(--black-alpha-48); letter-spacing: .02em; + margin-right: 6px; text-align: right; +} +.model-demo.dm-b .dm-param .meta-right .v { color: var(--accent-black); font-weight: 600; } +.model-demo.dm-b .dm-param .gen-btn { + height: 38px; padding: 0 20px; + background: var(--heat); color: var(--accent-white); + border: 0; border-radius: var(--r-md); + font-size: 13.5px; font-weight: 600; font-family: inherit; + cursor: pointer; + display: inline-flex; align-items: center; gap: 8px; + box-shadow: var(--shadow-cta); +} +.model-demo.dm-b .dm-param .gen-btn svg { width: 14px; height: 14px; } diff --git a/core/frontend/src/routes/ai-tools.tsx b/core/frontend/src/routes/ai-tools.tsx index f893c20..c80da1b 100644 --- a/core/frontend/src/routes/ai-tools.tsx +++ b/core/frontend/src/routes/ai-tools.tsx @@ -2,11 +2,13 @@ import { useEffect, useMemo, useState } from "react"; import { ArrowLeft, ArrowRight, + Bookmark, Check, ChevronDown, Download, Grid2X2, ImagePlus, + LayoutGrid, List, MoreHorizontal, Plus, @@ -14,7 +16,9 @@ import { RefreshCw, Search, Sparkles, - WandSparkles + Trash2, + WandSparkles, + X } from "lucide-react"; import type { AITask, Asset, ModelConfig, Product } from "../types"; import type { Page } from "./route-config"; @@ -845,6 +849,474 @@ function Pill({ ); } +/* ════════════════════════════════════════════════ + 模特图方案对比 Demo(纯静态展示 · 像素还原) + variant="A" → public/exact/model-photo-demo-a.html + variant="B" → public/exact/model-photo-demo-b.html + 左栏 = 商品空间(搜索 + 最近 6 条 + 全部入口),由真 products 填充,空则回退基线占位。 + 主区为静态方案展示(A:参数面板 + 结果双栏;B:任务流 + 底部 fixed 参数栏)。 + ════════════════════════════════════════════════ */ + +/* 基线左栏占位商品(无真 products 时兜底) */ +const DEMO_SIDE_PRODUCTS = [ + { id: "d1", title: "透真补水面膜", category: "美妆个护", batches: 6 }, + { id: "d2", title: "透真清透防晒霜", category: "美妆个护", batches: 3 }, + { id: "d3", title: "南卡 Lite Pro 蓝牙耳机", category: "数码 3C", batches: 2 }, + { id: "d4", title: "滋啦速食牛肉面", category: "食品饮料", batches: 1 }, + { id: "d5", title: "三顿半同款冻干咖啡", category: "食品饮料", batches: 1 }, + { id: "d6", title: "小熊 4L 可视空气炸锅", category: "家居家电", batches: 0 } +]; + export function ModelPhotoDemoPage({ variant, products, onBack }: { variant: "A" | "B"; products: Product[]; onBack: () => void }) { - return <>