Files
zt-closet-wxmini-frontend/stitch_ai_ui_v2/index.html
T
2026-09-15 16:01:59 +08:00

4124 lines
207 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>纸条 AI 衣橱 · UI 重构原型 V2</title>
<style>
/* ============================================================================
§1 设计令牌 · 零彩色灰阶 / 双字阶 / 间距 / 发丝线 / 玻璃 / 缓动
========================================================================== */
:root{
/* 墨阶 */
--ink:#0A0A0A;
--ink-2:#6E6E73;
--ink-3:#AEAEB2;
--ink-4:#C9C9CE;
--art:#B9B9BE; /* 衣物线稿色 */
/* 纸面 */
--paper:#FFFFFF;
--paper-2:#F7F7F5;
--paper-3:#EFEFED;
/* 发丝线与填充 */
--hairline:rgba(0,0,0,.08);
--hairline-2:rgba(0,0,0,.14);
--fill:rgba(120,120,128,.07);
--fill-2:rgba(120,120,128,.13);
/* 深色块(全稿唯一视觉锚点) */
--block:#1C1C1E;
--block-2:#2C2C2E;
/* 玻璃 */
--glass:rgba(255,255,255,.72);
--glass-2:rgba(255,255,255,.86);
--glass-dark:rgba(28,28,30,.82);
/* 字族 */
--serif:"Songti SC","STSong","Noto Serif SC","Source Han Serif SC",Georgia,"Times New Roman",serif;
--sans:-apple-system,BlinkMacSystemFont,"SF Pro Text","PingFang SC","Helvetica Neue",Arial,sans-serif;
/* 缓动 */
--ease:cubic-bezier(.32,.72,0,1);
--ease-out:cubic-bezier(.22,1,.36,1);
/* 圆角:仅小控件与抽屉使用圆角,大块内容保持直角 */
--r-img:4px;
--r-ctrl:10px;
--r-sheet:20px;
--r-pill:999px;
/* 度量 */
--pad:20px;
--status-h:48px;
--nav-h:44px;
--tab-h:60px;
--safe-b:14px;
}
/* ============================================================================
§2 基础层 · reset / 排版 / 工具类
========================================================================== */
*,*::before,*::after{box-sizing:border-box}
html,body{margin:0;padding:0}
body{
font-family:var(--sans);font-size:15px;line-height:1.6;color:var(--ink);
background:#E8E8E5;
-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;
text-rendering:optimizeLegibility;
}
button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:pointer;text-align:inherit}
input,textarea{font:inherit;color:inherit;border:0;background:none;outline:none;width:100%}
svg{display:block}
::selection{background:var(--ink);color:#fff}
/* 滚动条:极细发丝 */
.scroll::-webkit-scrollbar{width:0;height:0}
.wb-index::-webkit-scrollbar,.wb-nav::-webkit-scrollbar{width:4px}
.wb-index::-webkit-scrollbar-thumb,.wb-nav::-webkit-scrollbar-thumb{background:rgba(0,0,0,.14);border-radius:4px}
/* 排版 */
.eyebrow{font-size:10px;font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-3);line-height:1}
.display{font-family:var(--serif);font-size:34px;font-weight:500;letter-spacing:-.012em;line-height:1.14}
.t-xl{font-family:var(--serif);font-size:26px;font-weight:500;letter-spacing:-.01em;line-height:1.22}
.t-lg{font-family:var(--serif);font-size:20px;font-weight:500;letter-spacing:-.005em;line-height:1.32}
.t-md{font-size:17px;font-weight:600;line-height:1.38}
.t-bd{font-size:15px;line-height:1.62}
.t-sm{font-size:13px;line-height:1.55;color:var(--ink-2)}
.t-xs{font-size:11px;line-height:1.5;color:var(--ink-3)}
.t-quote{font-family:var(--serif);font-size:16px;line-height:1.85;letter-spacing:.005em;color:var(--ink)}
.num{font-variant-numeric:tabular-nums;font-feature-settings:"tnum" 1}
.c-ink{color:var(--ink)}.c-2{color:var(--ink-2)}.c-3{color:var(--ink-3)}
.hair{border-bottom:.5px solid var(--hairline)}
.hair-t{border-top:.5px solid var(--hairline)}
.gap-4{height:4px}.gap-8{height:8px}.gap-12{height:12px}.gap-16{height:16px}
.gap-20{height:20px}.gap-24{height:24px}.gap-32{height:32px}.gap-40{height:40px}
.pad{padding-left:var(--pad);padding-right:var(--pad)}
/* ============================================================================
§3 外壳层 · 工作台 / 索引 / 设备壳 / 状态栏 / 微信胶囊
========================================================================== */
.wb{display:grid;grid-template-columns:246px minmax(0,1fr) 212px;height:100vh;overflow:hidden}
/* 左索引 */
.wb-index{
border-right:.5px solid rgba(0,0,0,.09);background:#F1F1EE;
display:flex;flex-direction:column;min-height:0;overflow:hidden;
}
.wb-brand{padding:26px 20px 18px}
.wb-brand .eyebrow{margin-bottom:9px}
.wb-title{font-family:var(--serif);font-size:19px;font-weight:500;margin:0 0 5px;letter-spacing:-.01em}
.wb-sub{margin:0;font-size:11px;line-height:1.6;color:var(--ink-3)}
.wb-nav{flex:1;overflow-y:auto;padding:0 12px 24px}
.wb-grp{margin-top:18px}
.wb-grp-hd{font-size:9.5px;font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-3);padding:0 8px 7px}
.wb-item{
display:flex;align-items:center;gap:9px;width:100%;
padding:7px 9px;border-radius:8px;font-size:12.5px;color:var(--ink-2);
transition:background .16s var(--ease),color .16s var(--ease);
}
.wb-item:hover{background:rgba(0,0,0,.04);color:var(--ink)}
.wb-item.is-on{background:var(--ink);color:#fff}
.wb-item .wb-idx{font-size:9.5px;letter-spacing:.06em;opacity:.5;font-variant-numeric:tabular-nums}
.wb-item .wb-nm{flex:1;text-align:left}
.wb-item .wb-tag{font-size:9px;letter-spacing:.08em;opacity:.55}
.wb-foot{padding:14px 20px 18px;border-top:.5px solid rgba(0,0,0,.09);font-size:10px;color:var(--ink-3);letter-spacing:.04em}
/* 舞台 */
.wb-stage{
display:flex;flex-direction:column;align-items:center;justify-content:center;
gap:18px;min-height:0;overflow:auto;padding:28px 20px;
background:
radial-gradient(120% 80% at 50% 0%,#F4F4F1 0%,#E8E8E5 58%,#E2E2DF 100%);
}
.wb-hint{font-size:10.5px;letter-spacing:.06em;color:var(--ink-3);text-align:center;max-width:375px}
/* 设备壳 */
.device{
position:relative;width:375px;height:812px;flex-shrink:0;
background:var(--paper);border-radius:46px;overflow:hidden;
box-shadow:
0 0 0 1px rgba(0,0,0,.07),
0 1px 2px rgba(0,0,0,.05),
0 26px 60px -14px rgba(0,0,0,.24),
0 64px 120px -48px rgba(0,0,0,.20);
}
.island{
position:absolute;top:11px;left:50%;transform:translateX(-50%);
width:92px;height:26px;border-radius:14px;background:#0A0A0A;z-index:70;
}
.statusbar{
position:absolute;top:0;left:0;right:0;height:var(--status-h);z-index:65;
display:flex;align-items:center;justify-content:space-between;
padding:0 24px;pointer-events:none;
}
.sb-time{font-size:14px;font-weight:600;letter-spacing:.01em;font-variant-numeric:tabular-nums}
.sb-right{display:flex;align-items:center;gap:5px}
.sb-ic{height:11px;width:auto;color:var(--ink);fill:currentColor}
.sb-bat{height:11.5px;width:auto;color:var(--ink)}
/* 微信右上角胶囊 87×32 */
.capsule{
position:absolute;top:52px;right:12px;width:87px;height:32px;z-index:66;
border-radius:16px;border:.5px solid rgba(0,0,0,.10);
background:rgba(255,255,255,.62);
-webkit-backdrop-filter:saturate(180%) blur(14px);backdrop-filter:saturate(180%) blur(14px);
display:flex;align-items:center;justify-content:space-between;padding:0 10px;
color:var(--ink);pointer-events:none;
}
.capsule .cap-div{width:.5px;height:17px;background:rgba(0,0,0,.12)}
#app{position:absolute;inset:0;overflow:hidden}
/* 页面容器 */
.screen{
position:absolute;inset:0;background:var(--paper);
display:none;flex-direction:column;
}
.screen.is-active{display:flex;animation:screenIn .44s var(--ease) both}
@keyframes screenIn{
from{opacity:0;transform:translateX(16px) scale(.988)}
to{opacity:1;transform:none}
}
.screen .scroll{
position:absolute;inset:0;overflow-y:auto;overflow-x:hidden;
-webkit-overflow-scrolling:touch;
padding-top:calc(var(--status-h) + var(--nav-h));
padding-bottom:40px;
}
.screen[data-tab] .scroll{padding-bottom:104px}
/* ============================================================================
§4 玻璃层 · 导航 / 标签栏 / 分段条 / 弹层
========================================================================== */
.nav{
position:absolute;top:0;left:0;right:0;z-index:40;
transition:background .3s var(--ease),backdrop-filter .3s var(--ease),border-color .3s var(--ease);
border-bottom:.5px solid transparent;
}
.nav.is-glass{
background:var(--glass);
-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);
border-bottom-color:var(--hairline);
}
.nav-inner{
height:var(--nav-h);margin-top:var(--status-h);
display:flex;align-items:center;gap:6px;
padding-left:14px;padding-right:104px;
}
.nav-back{
width:34px;height:34px;margin-left:-4px;border-radius:50%;
display:flex;align-items:center;justify-content:center;color:var(--ink);
transition:background .16s var(--ease),transform .16s var(--ease);
}
.nav-back:active{background:var(--fill);transform:scale(.94)}
.nav-back svg{width:19px;height:19px}
.nav-title{
position:absolute;left:50%;top:var(--status-h);height:var(--nav-h);
transform:translateX(-50%);display:flex;align-items:center;
max-width:158px;font-size:16px;font-weight:600;letter-spacing:-.005em;
opacity:0;transition:opacity .26s var(--ease);pointer-events:none;
white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.nav.is-glass .nav-title{opacity:1}
.nav-action{
font-size:14px;color:var(--ink-2);letter-spacing:.01em;white-space:nowrap;
padding:6px 2px;transition:color .16s var(--ease),opacity .16s var(--ease);
}
.nav-action:active{opacity:.5}
.nav-action--ink{color:var(--ink);font-weight:500}
.nav-more{width:34px;height:34px;display:flex;align-items:center;justify-content:center;color:var(--ink)}
.nav-more svg{width:20px;height:20px}
/* 悬浮玻璃标签栏 */
.tabbar{
position:absolute;left:16px;right:16px;bottom:calc(var(--safe-b) + env(safe-area-inset-bottom,0px));
height:var(--tab-h);z-index:50;border-radius:30px;
background:var(--glass);
-webkit-backdrop-filter:saturate(180%) blur(22px);backdrop-filter:saturate(180%) blur(22px);
border:.5px solid rgba(255,255,255,.7);
box-shadow:0 0 0 .5px rgba(0,0,0,.05),0 10px 30px -10px rgba(0,0,0,.16);
display:flex;align-items:center;
transition:opacity .3s var(--ease),transform .3s var(--ease);
}
.tabbar[hidden]{display:none}
.tab-item{
position:relative;flex:1;height:100%;
display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;
color:var(--ink-3);transition:color .2s var(--ease);
}
.tab-item svg{width:21px;height:21px}
.tab-item .tab-tx{font-size:10px;letter-spacing:.02em}
.tab-item::after{
content:'';position:absolute;bottom:6px;left:50%;
width:14px;height:2px;border-radius:2px;background:var(--ink);
transform:translateX(-50%) scaleX(.3);opacity:0;
transition:opacity .24s var(--ease),transform .24s var(--ease);
}
.tab-item.is-on{color:var(--ink)}
.tab-item.is-on::after{opacity:1;transform:translateX(-50%) scaleX(1)}
.tab-badge{
position:absolute;top:11px;left:calc(50% + 5px);
min-width:15px;height:15px;padding:0 4px;border-radius:8px;
background:var(--ink);color:#fff;font-size:9px;font-weight:600;line-height:15px;
text-align:center;letter-spacing:0;font-variant-numeric:tabular-nums;
}
/* 粘性分段条 */
.segbar{
position:sticky;top:calc(var(--status-h) + var(--nav-h));z-index:20;
background:var(--glass);
-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);
border-bottom:.5px solid var(--hairline);
}
.seg{display:flex;gap:18px;padding:0 var(--pad);overflow-x:auto}
.seg::-webkit-scrollbar{display:none}
.seg-item{
position:relative;flex-shrink:0;padding:11px 0 12px;
font-size:14.5px;color:var(--ink-3);letter-spacing:.005em;
transition:color .2s var(--ease);
}
.seg-item.is-on{color:var(--ink);font-weight:500}
.seg-item.is-on::after{
content:'';position:absolute;left:0;right:0;bottom:-.5px;height:1.5px;
background:var(--ink);border-radius:2px;
}
/* 弹层根 */
.overlayRoot{position:absolute;inset:0;z-index:80;pointer-events:none}
.layer{position:absolute;inset:0;display:none;pointer-events:none}
.layer.is-open{display:block;pointer-events:auto}
.scrim{
position:absolute;inset:0;background:rgba(0,0,0,.28);
-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);
animation:fadeIn .28s var(--ease) both;
}
@keyframes fadeIn{from{opacity:0}to{opacity:1}}
/* Modal */
.modal-wrap{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;padding:0 34px;pointer-events:none}
.modal{pointer-events:auto}
.modal{
width:100%;max-width:288px;border-radius:var(--r-sheet);overflow:hidden;
background:var(--glass-2);
-webkit-backdrop-filter:saturate(180%) blur(30px);backdrop-filter:saturate(180%) blur(30px);
border:.5px solid rgba(255,255,255,.7);
box-shadow:0 24px 60px -18px rgba(0,0,0,.32);
animation:modalIn .42s var(--ease) both;
}
@keyframes modalIn{from{opacity:0;transform:scale(.94)}to{opacity:1;transform:none}}
.modal-body{padding:22px 20px 18px;text-align:center}
.modal-title{font-family:var(--serif);font-size:18px;font-weight:500;letter-spacing:-.005em}
.modal-text{margin-top:8px;font-size:13px;line-height:1.6;color:var(--ink-2)}
.modal-input{
margin-top:14px;height:40px;border-radius:8px;background:rgba(120,120,128,.10);
padding:0 12px;font-size:14px;
}
.modal-acts{display:flex;border-top:.5px solid var(--hairline)}
.modal-act{
flex:1;height:48px;display:flex;align-items:center;justify-content:center;
font-size:16px;color:var(--ink-2);transition:background .16s var(--ease);
}
.modal-act:active{background:var(--fill)}
.modal-act + .modal-act{border-left:.5px solid var(--hairline)}
.modal-act--main{color:var(--ink);font-weight:600}
/* Sheet 底部抽屉 */
.sheet-wrap{position:absolute;inset:0;display:flex;align-items:flex-end}
.sheet{
width:100%;border-radius:var(--r-sheet) var(--r-sheet) 0 0;overflow:hidden;
background:var(--glass-2);
-webkit-backdrop-filter:saturate(180%) blur(30px);backdrop-filter:saturate(180%) blur(30px);
border-top:.5px solid rgba(255,255,255,.7);
box-shadow:0 -18px 50px -20px rgba(0,0,0,.28);
animation:sheetIn .46s var(--ease) both;
max-height:86%;display:flex;flex-direction:column;
}
@keyframes sheetIn{from{transform:translateY(101%)}to{transform:none}}
.sheet-grab{width:36px;height:4px;border-radius:2px;background:var(--ink-4);margin:8px auto 0}
.sheet-hd{
display:flex;align-items:center;justify-content:space-between;gap:12px;
padding:14px var(--pad) 12px;
}
.sheet-hd .sheet-t{font-size:16px;font-weight:600;letter-spacing:-.005em}
.sheet-hd .sheet-x{font-size:14px;color:var(--ink-2)}
.sheet-body{overflow-y:auto;padding-bottom:calc(16px + env(safe-area-inset-bottom,0px))}
.sheet-foot{
padding:12px var(--pad) calc(16px + env(safe-area-inset-bottom,0px));
border-top:.5px solid var(--hairline);
}
/* ActionSheet */
.as-wrap{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:flex-end;padding:0 8px calc(8px + env(safe-area-inset-bottom,0px));pointer-events:none}
.as-wrap > *{pointer-events:auto}
.as-card{
border-radius:14px;overflow:hidden;background:var(--glass-2);
-webkit-backdrop-filter:saturate(180%) blur(30px);backdrop-filter:saturate(180%) blur(30px);
border:.5px solid rgba(255,255,255,.7);
box-shadow:0 -10px 40px -18px rgba(0,0,0,.3);
animation:asIn .4s var(--ease) both;
}
@keyframes asIn{from{opacity:0;transform:translateY(24px)}to{opacity:1;transform:none}}
.as-hd{padding:13px 16px;text-align:center;font-size:12.5px;color:var(--ink-3);border-bottom:.5px solid var(--hairline)}
.as-item{
display:block;width:100%;height:52px;line-height:52px;text-align:center;
font-size:17px;color:var(--ink);border-bottom:.5px solid var(--hairline);
transition:background .16s var(--ease);
}
.as-item:last-child{border-bottom:0}
.as-item:active{background:var(--fill)}
.as-cancel{
margin-top:8px;display:block;width:100%;height:52px;line-height:52px;text-align:center;
font-size:17px;font-weight:600;color:var(--ink);border-radius:14px;
background:var(--glass-2);
-webkit-backdrop-filter:saturate(180%) blur(30px);backdrop-filter:saturate(180%) blur(30px);
border:.5px solid rgba(255,255,255,.7);
}
.as-cancel:active{background:var(--fill-2)}
/* Toast */
.toast-layer .toast-wrap{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;pointer-events:none}
.toast{
max-width:230px;padding:13px 20px;border-radius:14px;
background:var(--glass-dark);color:#fff;font-size:13.5px;line-height:1.5;text-align:center;
-webkit-backdrop-filter:blur(24px);backdrop-filter:blur(24px);
box-shadow:0 18px 44px -16px rgba(0,0,0,.5);
animation:toastIn .34s var(--ease) both;
}
@keyframes toastIn{from{opacity:0;transform:scale(.92) translateY(6px)}to{opacity:1;transform:none}}
.toast.is-out{animation:toastOut .26s var(--ease) both}
@keyframes toastOut{to{opacity:0;transform:scale(.96)}}
/* ============================================================================
§5 组件层
========================================================================== */
/* 按钮 */
.btn{
display:inline-flex;align-items:center;justify-content:center;gap:7px;
height:50px;padding:0 22px;border-radius:var(--r-pill);
font-size:15px;font-weight:500;letter-spacing:.01em;white-space:nowrap;
transition:transform .18s var(--ease),opacity .18s var(--ease),background .2s var(--ease);
}
.btn:active{transform:scale(.972);opacity:.74}
.btn svg{width:17px;height:17px}
.btn--block{display:flex;width:100%}
.btn--sm{height:36px;padding:0 15px;font-size:13.5px}
.btn--ink{background:var(--ink);color:#fff}
.btn--ink.is-off{background:var(--fill-2);color:var(--ink-3);pointer-events:none}
.btn--ghost{box-shadow:inset 0 0 0 .5px var(--hairline-2);color:var(--ink)}
.btn--plain{background:var(--fill);color:var(--ink)}
.btn--glass{
background:var(--glass-2);
-webkit-backdrop-filter:saturate(180%) blur(22px);backdrop-filter:saturate(180%) blur(22px);
border:.5px solid rgba(255,255,255,.7);
box-shadow:0 8px 24px -10px rgba(0,0,0,.18);color:var(--ink);
}
.btn--text{
height:auto;padding:0;border-radius:0;font-size:14px;font-weight:400;
color:var(--ink);text-decoration:underline;
text-underline-offset:3.5px;text-decoration-thickness:.5px;text-decoration-color:var(--ink-4);
}
.btn--text:active{opacity:.5;transform:none}
/* 胶囊标签 */
.pill{
display:inline-flex;align-items:center;gap:4px;height:23px;padding:0 9px;
border-radius:var(--r-pill);font-size:11px;font-weight:500;letter-spacing:.015em;
background:var(--fill);color:var(--ink-2);white-space:nowrap;
}
.pill--ink{background:var(--ink);color:#fff}
.pill--line{background:transparent;box-shadow:inset 0 0 0 .5px var(--hairline-2);color:var(--ink-2)}
.pill--plain{background:transparent;color:var(--ink-3);padding:0 2px}
.pill--dot::before{content:'';width:5px;height:5px;border-radius:50%;background:currentColor;opacity:.55}
.pill svg{width:12px;height:12px}
/* 列表行 */
.rows{background:var(--paper)}
.row{
display:flex;align-items:center;gap:12px;min-height:52px;width:100%;
padding:0 var(--pad);border-bottom:.5px solid var(--hairline);
transition:background .16s var(--ease);
}
.row:active{background:var(--fill)}
.row-lb{flex:1;font-size:15px;line-height:1.4}
.row-vl{font-size:13.5px;color:var(--ink-3);font-variant-numeric:tabular-nums}
.row-ch{width:13px;height:13px;color:var(--ink-4);flex-shrink:0}
.row-ic{width:19px;height:19px;color:var(--ink-2);flex-shrink:0}
.row-badge{
min-width:17px;height:17px;padding:0 5px;border-radius:9px;background:var(--ink);color:#fff;
font-size:10px;font-weight:600;line-height:17px;text-align:center;font-variant-numeric:tabular-nums;
}
/* 分组标题 */
.grp-hd{display:flex;align-items:baseline;gap:9px;padding:0 var(--pad) 11px}
.grp-hd .gh-cn{font-size:13px;font-weight:600;letter-spacing:.01em;color:var(--ink)}
.grp-hd .gh-en{font-size:9.5px;font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-3)}
.grp-line{height:.5px;background:var(--hairline);margin:0 var(--pad) 4px}
/* 规格表(衣物属性) */
.spec{display:flex;align-items:flex-start;gap:14px;padding:11px var(--pad);border-bottom:.5px solid var(--hairline)}
.spec-k{width:80px;flex-shrink:0;font-size:13px;color:var(--ink-2);line-height:1.5}
.spec-v{flex:1;font-size:14.5px;line-height:1.5;text-align:right;color:var(--ink)}
.spec-v .dot{display:inline-block;width:9px;height:9px;border-radius:50%;margin-right:6px;vertical-align:-1px;box-shadow:inset 0 0 0 .5px rgba(0,0,0,.14)}
/* 数字条(额度概览) */
.stats{display:flex;border-top:.5px solid var(--hairline);border-bottom:.5px solid var(--hairline)}
.stat{flex:1;padding:14px 0 15px;text-align:center;position:relative}
.stat + .stat::before{content:'';position:absolute;left:0;top:14px;bottom:15px;width:.5px;background:var(--hairline)}
.stat-n{font-family:var(--serif);font-size:24px;font-weight:500;line-height:1;letter-spacing:-.01em;font-variant-numeric:tabular-nums}
.stat-n small{font-size:12px;color:var(--ink-3);margin-left:2px}
.stat-l{margin-top:6px;font-size:9.5px;font-weight:600;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-3)}
/* 进度轨 */
.track{height:1.5px;background:var(--hairline-2);position:relative;overflow:hidden}
.track > i{position:absolute;left:0;top:0;bottom:0;background:var(--ink);display:block}
.track.is-warn > i{background:var(--ink-2)}
/* 评分点阵 */
.dots{display:inline-flex;gap:5px;vertical-align:middle}
.dots i{width:8px;height:8px;border-radius:50%;box-shadow:inset 0 0 0 1px var(--ink-4)}
.dots i.on{background:var(--ink);box-shadow:none}
/* 刻度尺(运势三项评分) */
.scale{position:relative;height:26px}
.scale-line{position:absolute;left:0;right:0;top:12px;height:1px;background:var(--hairline-2)}
.scale-fill{position:absolute;left:0;top:12px;height:1px;background:var(--ink)}
.scale-pip{position:absolute;top:8.5px;width:8px;height:8px;border-radius:50%;background:var(--ink);transform:translateX(-50%)}
.scale-ticks{position:absolute;left:0;right:0;top:10px;height:5px;display:flex;justify-content:space-between}
.scale-ticks i{width:.5px;height:5px;background:var(--hairline-2)}
/* 衣物线稿方图 */
.tile-img{
position:relative;width:100%;aspect-ratio:1/1;background:var(--paper-2);
border-radius:var(--r-img);display:flex;align-items:center;justify-content:center;overflow:hidden;
}
.tile-img svg{width:56%;height:56%;color:var(--art)}
.tile-img.is-empty svg{width:34%;height:34%;color:var(--ink-4)}
.tile-name{margin-top:9px;font-family:var(--serif);font-size:14px;line-height:1.35;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tile-sub{margin-top:2px;font-size:10.5px;color:var(--ink-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tile-flag{
position:absolute;top:7px;left:7px;height:19px;padding:0 7px;border-radius:10px;
background:var(--glass-2);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);
font-size:9.5px;font-weight:500;line-height:19px;color:var(--ink-2);
}
.tile-check{
position:absolute;right:7px;bottom:7px;width:20px;height:20px;border-radius:50%;
box-shadow:inset 0 0 0 1px rgba(255,255,255,.9),0 0 0 .5px rgba(0,0,0,.12);
background:rgba(255,255,255,.55);
-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
display:flex;align-items:center;justify-content:center;color:#fff;
transition:background .18s var(--ease),color .18s var(--ease);
}
.tile-check svg{width:12px;height:12px;opacity:0}
.is-picked .tile-check{background:var(--ink)}
.is-picked .tile-check svg{opacity:1}
.is-picked .tile-img{box-shadow:inset 0 0 0 1.5px var(--ink)}
/* 拼图封面 */
.collage{
position:relative;display:grid;gap:1px;background:var(--paper);
border-radius:var(--r-img);overflow:hidden;
aspect-ratio:1/1;grid-template-columns:1fr 1fr;
}
.collage[data-n="1"]{grid-template-columns:1fr;aspect-ratio:1/1}
.collage[data-n="2"]{grid-template-columns:1fr 1fr;grid-template-rows:1fr;aspect-ratio:2/1}
.collage[data-n="3"]{grid-template-columns:1fr 1fr;grid-template-rows:1fr 1fr}
.collage[data-n="3"] > *:first-child{grid-row:span 2}
.collage > .cg{position:relative;background:var(--paper-2);display:flex;align-items:center;justify-content:center;overflow:hidden;min-width:0;min-height:0}
.collage > .cg svg{width:54px;height:54px;flex-shrink:0;color:var(--art)}
.cg-more{
position:absolute;inset:0;background:rgba(255,255,255,.7);
-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
display:flex;align-items:center;justify-content:center;
font-family:var(--serif);font-size:17px;color:var(--ink);
}
.cg-badge{
position:absolute;right:8px;bottom:8px;height:21px;padding:0 8px;border-radius:11px;
background:var(--glass-2);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);
font-size:10.5px;line-height:21px;color:var(--ink);font-variant-numeric:tabular-nums;
}
/* 骨架屏 */
.sk{background:linear-gradient(90deg,#F2F2F0 25%,#E9E9E6 37%,#F2F2F0 63%);background-size:400% 100%;animation:skLoad 1.5s ease infinite}
@keyframes skLoad{0%{background-position:100% 50%}100%{background-position:0 50%}}
.sk-img{width:100%;aspect-ratio:1/1;border-radius:var(--r-img)}
.sk-ln{height:10px;border-radius:5px}
/* 空态 */
.empty{display:flex;flex-direction:column;align-items:center;text-align:center;padding:64px 44px 0}
.empty-ic{width:52px;height:52px;color:var(--ink-4);margin-bottom:20px}
.empty-t{font-family:var(--serif);font-size:19px;font-weight:500;letter-spacing:-.005em}
.empty-d{margin-top:8px;font-size:13px;line-height:1.7;color:var(--ink-2);max-width:240px}
.empty-b{margin-top:24px}
/* 页脚提示 */
.foot-note{padding:26px 0 8px;text-align:center;font-size:11px;color:var(--ink-4);letter-spacing:.06em}
/* 大标题页头 */
.head{padding:20px var(--pad) 0}
.head .eyebrow{margin-bottom:10px}
.head-row{display:flex;align-items:flex-end;justify-content:space-between;gap:14px}
.head-meta{font-size:11px;color:var(--ink-3);letter-spacing:.02em;padding-bottom:6px;text-align:right;line-height:1.6;font-variant-numeric:tabular-nums}
/* 悬浮双按钮条(穿搭页) */
.float-duo{
position:absolute;left:16px;right:16px;bottom:calc(var(--tab-h) + 24px + env(safe-area-inset-bottom,0px));
z-index:45;display:flex;gap:9px;
}
.float-duo .btn{flex:1;height:46px;font-size:14px}
/* 悬浮底部操作条 */
.dock{
position:absolute;left:0;right:0;bottom:0;z-index:45;
padding:12px var(--pad) calc(14px + env(safe-area-inset-bottom,0px));
background:var(--glass);
-webkit-backdrop-filter:saturate(180%) blur(22px);backdrop-filter:saturate(180%) blur(22px);
border-top:.5px solid var(--hairline);
}
.dock-row{display:flex;align-items:center;gap:12px}
.dock-ic{
display:flex;align-items:center;gap:5px;font-size:12.5px;color:var(--ink-2);
font-variant-numeric:tabular-nums;transition:color .18s var(--ease),transform .18s var(--ease);
}
.dock-ic svg{width:21px;height:21px}
.dock-ic.is-on{color:var(--ink)}
.dock-ic.is-on svg{color:var(--ink)}
.dock-ic:active{transform:scale(.92)}
/* 状态与视图容器 */
.st{display:none}
[data-state="list"] .st[data-when="list"],
[data-state="empty"] .st[data-when="empty"],
[data-state="skeleton"] .st[data-when="skeleton"],
[data-state="error"] .st[data-when="error"],
[data-state="idle"] .st[data-when="idle"],
[data-state="processing"] .st[data-when="processing"],
[data-state="failed"] .st[data-when="failed"],
[data-state="invalid"] .st[data-when="invalid"],
[data-state="success"] .st[data-when="success"],
[data-state="generating"] .st[data-when="generating"],
[data-state="result"] .st[data-when="result"],
[data-state="needlogin"] .st[data-when="needlogin"],
[data-state="submitting"] .st[data-when="submitting"]{display:block}
.vw{display:none}
[data-view="form"] .vw[data-when="form"],
[data-view="select"] .vw[data-when="select"],
[data-view="config"] .vw[data-when="config"],
[data-view="success"] .vw[data-when="success"],
[data-view="mall"] .vw[data-when="mall"],
[data-view="flow"] .vw[data-when="flow"]{display:block}
/* 全局微工具 */
.spacer{flex:1}
.center{display:flex;align-items:center;justify-content:center}
.stack{display:flex;flex-direction:column}
/* 变量开关(同一屏内的角色差异) */
[data-owner="1"] .only-visitor{display:none}
[data-owner="0"] .only-owner{display:none}
[data-readonly="1"] .only-editable{display:none}
[data-readonly="0"] .only-readonly{display:none}
[data-seg="0"] .seg-c1,[data-seg="0"] .seg-c2,
[data-seg="1"] .seg-c0,[data-seg="1"] .seg-c2,
[data-seg="2"] .seg-c0,[data-seg="2"] .seg-c1{display:none}
/* 右状态面板 */
.wb-state{
border-left:.5px solid rgba(0,0,0,.09);background:#F1F1EE;
display:flex;flex-direction:column;min-height:0;overflow:hidden;
}
.wb-state-hd{padding:26px 18px 12px;font-size:9.5px;font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-3)}
.wb-state-bd{flex:1;overflow-y:auto;padding:0 14px 24px}
.wb-chip{
display:block;width:100%;padding:7px 10px;margin-bottom:5px;border-radius:7px;
font-size:12px;color:var(--ink-2);text-align:left;
transition:background .16s var(--ease),color .16s var(--ease);
}
.wb-chip:hover{background:rgba(0,0,0,.045)}
.wb-chip.is-on{background:var(--ink);color:#fff}
.wb-sec{margin:16px 0 7px;padding:0 10px;font-size:9.5px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3)}
.wb-note{margin:10px 10px 0;font-size:10.5px;line-height:1.7;color:var(--ink-3)}
.wb-note code{font-family:var(--sans);background:rgba(0,0,0,.055);padding:1px 4px;border-radius:3px;font-size:10px}
/* 响应式:窄屏堆叠 */
@media (max-width:1180px){
.wb{grid-template-columns:1fr;grid-template-rows:auto minmax(0,1fr) auto;height:auto;min-height:100vh;overflow:visible}
.wb-index{flex-direction:row;align-items:center;border-right:0;border-bottom:.5px solid rgba(0,0,0,.09);padding:0 12px;overflow-x:auto}
.wb-brand{padding:12px 14px 12px 4px;flex-shrink:0}
.wb-title{font-size:14px}.wb-sub{display:none}
.wb-nav{display:flex;gap:6px;padding:0 0 0 6px;overflow:visible}
.wb-grp{display:flex;gap:6px;margin:0}
.wb-grp-hd{display:none}
.wb-item{width:auto;white-space:nowrap}
.wb-item .wb-idx,.wb-item .wb-tag{display:none}
.wb-foot{display:none}
.wb-stage{padding:20px 12px}
.wb-state{border-left:0;border-top:.5px solid rgba(0,0,0,.09)}
.wb-state-hd{padding:14px 18px 8px}
.wb-state-bd{display:flex;flex-wrap:wrap;gap:6px;padding:0 14px 16px}
.wb-chip{width:auto;margin:0}
.wb-sec{width:100%;margin:8px 0 2px}
.wb-note{width:100%}
}
@media (max-width:420px){
.device{transform:scale(.88);transform-origin:top center;margin-bottom:-96px}
}
/* ============================================================================
§6.1 登录
========================================================================== */
.screen[data-screen="login"] .scroll{display:flex;flex-direction:column;padding:0 0 calc(26px + env(safe-area-inset-bottom,0px))}
.lg-top{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:64px 32px 0}
.lg-hero{position:relative;width:100%;height:170px;margin-bottom:10px}
.lg-hero svg{position:absolute;color:var(--ink-4)}
.lg-ic1{left:5%;top:6%;width:30px;height:30px;transform:rotate(-13deg);opacity:.52}
.lg-ic2{left:27%;top:54%;width:21px;height:21px;transform:rotate(9deg);opacity:.34}
.lg-ic3{right:7%;top:12%;width:26px;height:26px;transform:rotate(15deg);opacity:.46}
.lg-ic4{right:24%;bottom:0%;width:20px;height:20px;transform:rotate(-7deg);opacity:.3}
.lg-ic5{left:13%;bottom:5%;width:17px;height:17px;opacity:.28}
.lg-logo{
width:62px;height:62px;border-radius:50%;margin-bottom:22px;color:var(--ink);
box-shadow:inset 0 0 0 .5px var(--hairline-2);
display:flex;align-items:center;justify-content:center;
}
.lg-logo svg{width:27px;height:27px}
.lg-name{font-family:var(--serif);font-size:27px;font-weight:500;letter-spacing:.08em;text-indent:.08em;margin:0;line-height:1.2}
.lg-slogan{margin:12px 0 0;font-size:13px;color:var(--ink-2);letter-spacing:.03em}
.lg-foot{padding:0 28px}
.lg-terms{margin:16px 0 0;text-align:center;font-size:11px;line-height:1.75;color:var(--ink-3)}
.lg-terms a{color:var(--ink-2);text-decoration:underline;text-underline-offset:3px;text-decoration-thickness:.5px;text-decoration-color:var(--ink-4)}
.lg-gift-ic{width:44px;height:44px;border-radius:50%;margin:0 auto 16px;color:var(--ink);box-shadow:inset 0 0 0 .5px var(--hairline-2);display:flex;align-items:center;justify-content:center}
.lg-gift-ic svg{width:20px;height:20px}
.lg-gift-list{margin-top:4px;text-align:left}
.lg-gift-row{display:flex;align-items:center;gap:10px;padding:11px 0;border-bottom:.5px solid var(--hairline)}
.lg-gift-row:last-child{border-bottom:0}
.lg-gift-row svg{width:16px;height:16px;color:var(--ink-2);flex-shrink:0}
.lg-gift-row .gn{flex:1;font-size:13px}
.lg-gift-row .gv{font-size:12px;color:var(--ink-3);font-variant-numeric:tabular-nums}
/* ============================================================================
§6.2 衣橱
========================================================================== */
.wd-stat{margin-top:11px;font-size:11.5px;color:var(--ink-3);letter-spacing:.02em}
.wd-grid{display:grid;grid-template-columns:1fr 1fr;gap:22px 13px;padding:20px var(--pad) 0}
.wd-tile{display:block;width:100%;transition:transform .2s var(--ease)}
.wd-tile:active{transform:scale(.975)}
.wd-skel{display:grid;grid-template-columns:1fr 1fr;gap:22px 13px;padding:20px var(--pad) 0}
.wd-skel > div{display:flex;flex-direction:column;gap:9px}
.fab{
position:absolute;right:18px;bottom:calc(var(--tab-h) + 28px + env(safe-area-inset-bottom,0px));
width:54px;height:54px;border-radius:50%;z-index:46;
background:var(--ink);color:#fff;
display:flex;align-items:center;justify-content:center;
box-shadow:0 14px 30px -10px rgba(0,0,0,.45);
transition:transform .2s var(--ease),opacity .2s var(--ease);
}
.fab:active{transform:scale(.92);opacity:.86}
.fab svg{width:22px;height:22px}
/* ============================================================================
§6.3 穿搭
========================================================================== */
[data-screen="outfit"] .scroll{padding-bottom:166px}
.of-list{padding:20px var(--pad) 0;display:flex;flex-direction:column;gap:28px}
.of-card{display:block;width:100%;transition:transform .2s var(--ease)}
.of-card:active{transform:scale(.985)}
.of-author{display:flex;align-items:center;gap:8px;margin-bottom:10px}
.of-av{width:24px;height:24px;border-radius:50%;background:var(--paper-3);color:var(--ink-3);display:flex;align-items:center;justify-content:center;overflow:hidden;flex-shrink:0}
.of-av svg{width:13px;height:13px}
.of-aname{font-size:12.5px;letter-spacing:.01em}
.of-atime{margin-left:auto;font-size:11px;color:var(--ink-3)}
.of-trow{display:flex;align-items:baseline;gap:9px;margin-top:12px}
.of-title{font-family:var(--serif);font-size:17px;font-weight:500;line-height:1.35;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.of-desc{
margin-top:7px;font-size:12.5px;line-height:1.62;color:var(--ink-2);
display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
.of-meta{display:flex;align-items:center;gap:11px;margin-top:12px}
.of-meta .m{display:inline-flex;align-items:center;gap:4px;font-size:11px;color:var(--ink-3);font-variant-numeric:tabular-nums}
.of-meta .m svg{width:13px;height:13px}
.of-skel{padding:20px var(--pad) 0;display:flex;flex-direction:column;gap:28px}
.of-skel > div{display:flex;flex-direction:column;gap:12px}
/* ============================================================================
§6.4 运势
========================================================================== */
.hs-hero{padding:22px var(--pad) 0;display:flex;align-items:baseline;justify-content:space-between;gap:12px}
.hs-zodiac{display:flex;align-items:center;gap:9px}
.hs-zodiac svg{width:20px;height:20px;color:var(--ink-2);flex-shrink:0}
.hs-date{font-size:11px;color:var(--ink-3);letter-spacing:.08em;font-variant-numeric:tabular-nums}
.hs-score{padding:28px var(--pad) 0;display:flex;align-items:flex-end;gap:20px}
.hs-num{font-family:var(--serif);font-size:76px;font-weight:500;line-height:.84;letter-spacing:-.035em;font-variant-numeric:tabular-nums}
.hs-stars{display:flex;gap:4px;padding-bottom:9px}
.hs-stars svg{width:15px;height:15px;color:var(--ink)}
.hs-scales{padding:32px var(--pad) 0;display:flex;flex-direction:column;gap:19px}
.hs-st{display:flex;align-items:baseline;justify-content:space-between;margin-bottom:7px}
.hs-st .k{font-size:13px;color:var(--ink-2)}
.hs-st .v{font-size:11.5px;color:var(--ink-3);font-variant-numeric:tabular-nums;letter-spacing:.04em}
.hs-quote{padding:32px var(--pad) 0}
.hs-quote .qt{margin-top:13px;font-family:var(--serif);font-size:15.5px;line-height:1.92;letter-spacing:.004em}
.hs-lucky{display:flex;margin:32px var(--pad) 0;border-top:.5px solid var(--hairline);border-bottom:.5px solid var(--hairline)}
.hs-lucky > div{flex:1;padding:16px 0 17px;text-align:center;position:relative}
.hs-lucky > div + div::before{content:'';position:absolute;left:0;top:16px;bottom:17px;width:.5px;background:var(--hairline)}
.hs-lucky .lk{font-size:9.5px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3)}
.hs-lucky .lv{margin-top:10px;font-family:var(--serif);font-size:19px;display:flex;align-items:center;justify-content:center;gap:7px}
.hs-lucky .lv i{width:11px;height:11px;border-radius:50%;box-shadow:inset 0 0 0 .5px rgba(0,0,0,.14)}
/* ============================================================================
§6.5 分享列表
========================================================================== */
.cs-list{padding:14px var(--pad) 0;display:flex;flex-direction:column}
.cs-card{display:flex;gap:13px;padding:16px 0;border-bottom:.5px solid var(--hairline);width:100%;align-items:flex-start;transition:opacity .2s var(--ease),transform .2s var(--ease)}
.cs-card:active{transform:scale(.985)}
.cs-card.is-dead{opacity:.38}
.cs-thumb{
width:72px;height:72px;flex-shrink:0;border-radius:var(--r-img);background:var(--paper-2);
overflow:hidden;display:grid;grid-template-columns:1fr 1fr;grid-template-rows:1fr 1fr;gap:1px;
}
.cs-thumb .c{display:flex;align-items:center;justify-content:center;background:var(--paper-2);min-width:0;min-height:0;overflow:hidden}
.cs-thumb .c svg{width:20px;height:20px;flex-shrink:0;color:var(--art)}
.cs-thumb.is-photo{display:flex;align-items:center;justify-content:center;background:var(--paper-2)}
.cs-thumb.is-photo svg{width:52%;height:52%;color:var(--art)}
.cs-body{flex:1;min-width:0}
.cs-owner{display:flex;align-items:center;gap:6px;margin-bottom:7px}
.cs-owner .oav{width:18px;height:18px;border-radius:50%;background:var(--paper-3);color:var(--ink-3);display:flex;align-items:center;justify-content:center;flex-shrink:0}
.cs-owner .oav svg{width:10px;height:10px}
.cs-owner .onm{font-size:11.5px;color:var(--ink-2)}
.cs-t{font-family:var(--serif);font-size:15px;line-height:1.35;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cs-tags{display:flex;align-items:center;gap:7px;margin-top:9px;flex-wrap:wrap}
.cs-exp{font-size:11px;color:var(--ink-3);font-variant-numeric:tabular-nums}
/* ============================================================================
§6.6 我的
========================================================================== */
.pf-hero{display:flex;align-items:center;gap:16px;padding:24px var(--pad) 0}
.pf-av{
width:72px;height:72px;border-radius:50%;flex-shrink:0;overflow:hidden;
background:var(--paper-3);color:var(--ink-3);
display:flex;align-items:center;justify-content:center;
}
.pf-av svg{width:31px;height:31px}
.pf-name{font-family:var(--serif);font-size:23px;font-weight:500;letter-spacing:-.005em;line-height:1.2}
.pf-sub{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}
.pf-edit{margin-left:auto;display:flex;align-items:center;gap:1px;font-size:12.5px;color:var(--ink-3);flex-shrink:0}
.pf-edit svg{width:12px;height:12px}
.pf-warn{
margin:22px var(--pad) 0;padding:13px 15px;border-radius:var(--r-ctrl);background:var(--fill);
display:flex;align-items:center;gap:10px;font-size:12.5px;line-height:1.55;
}
.pf-warn svg{width:16px;height:16px;flex-shrink:0;color:var(--ink-2)}
.pf-quota{display:block;width:100%;margin-top:24px;text-align:left}
.pf-quota-hd{display:flex;align-items:center;gap:8px;padding:0 var(--pad) 13px}
.pf-quota-hd .qk{font-size:13px;font-weight:600}
.pf-quota-hd svg{width:12px;height:12px;color:var(--ink-4);margin-left:auto}
.pf-tracks{display:flex;flex-direction:column;gap:0}
.pf-track{padding:0 var(--pad) 15px}
.pf-track .tt{display:flex;align-items:baseline;justify-content:space-between;margin-bottom:8px}
.pf-track .tt .n{font-size:12px;color:var(--ink-2)}
.pf-track .tt .v{font-size:11.5px;color:var(--ink-3);font-variant-numeric:tabular-nums}
.pf-ver{padding:26px 0 6px;text-align:center;font-size:11px;color:var(--ink-4);letter-spacing:.06em}
[data-seg="2"] .of-hide-community{display:none}
[data-seg="1"] .of-hide-collect{display:none}
/* ============================================================================
§6.7 上传衣物
========================================================================== */
.up-drop{
display:flex;flex-direction:column;align-items:center;justify-content:center;
width:calc(100% - var(--pad) * 2);margin:28px var(--pad) 0;padding:54px 24px;
border:1px dashed var(--hairline-2);border-radius:var(--r-img);
transition:background .2s var(--ease),border-color .2s var(--ease);
}
.up-drop:active{background:var(--fill);border-color:var(--ink-4)}
.up-drop-ic{width:34px;height:34px;color:var(--ink-3);margin-bottom:18px}
.up-drop-t{font-family:var(--serif);font-size:17px;font-weight:500}
.up-drop-d{margin-top:9px;font-size:11.5px;color:var(--ink-3);letter-spacing:.01em}
.up-note{margin-top:22px;text-align:center;font-size:11.5px;color:var(--ink-3);letter-spacing:.01em}
.up-preview{
margin:26px var(--pad) 0;aspect-ratio:4/5;background:var(--paper-2);
border-radius:var(--r-img);display:flex;align-items:center;justify-content:center;overflow:hidden;
}
.up-preview svg{width:44%;height:44%;color:var(--art)}
.up-steps{padding:32px var(--pad) 0;display:flex;flex-direction:column}
.up-step{display:flex;align-items:center;gap:14px;position:relative;padding-bottom:24px}
.up-step:last-child{padding-bottom:0}
.up-step::before{content:'';position:absolute;left:4.75px;top:13px;bottom:0;width:.5px;background:var(--hairline-2)}
.up-step:last-child::before{display:none}
.up-dot{
width:10px;height:10px;border-radius:50%;flex-shrink:0;background:var(--paper);
box-shadow:inset 0 0 0 1px var(--ink-4);position:relative;z-index:1;
}
.up-step.is-done .up-dot{background:var(--ink);box-shadow:none}
.up-step.is-on .up-dot{box-shadow:inset 0 0 0 1px var(--ink);animation:dotPulse 1.8s var(--ease) infinite}
@keyframes dotPulse{
0%,100%{box-shadow:inset 0 0 0 1px var(--ink),0 0 0 0 rgba(10,10,10,.18)}
55%{box-shadow:inset 0 0 0 1px var(--ink),0 0 0 6px rgba(10,10,10,0)}
}
.up-lb{font-size:13.5px;color:var(--ink-3);letter-spacing:.01em}
.up-step.is-done .up-lb,.up-step.is-on .up-lb{color:var(--ink)}
.up-bang{
width:46px;height:46px;border-radius:50%;margin-bottom:22px;
box-shadow:inset 0 0 0 .5px var(--hairline-2);
display:flex;align-items:center;justify-content:center;
font-family:var(--serif);font-size:23px;line-height:1;
}
.up-duo{display:flex;gap:10px;padding:28px var(--pad) 0}
.up-duo .btn{flex:1}
/* ============================================================================
§6.8 衣物详情
========================================================================== */
[data-screen="clothes-detail"] .scroll{padding-bottom:124px}
.cd-photo{
margin:16px var(--pad) 0;aspect-ratio:4/5;background:var(--paper-2);
border-radius:var(--r-img);display:flex;align-items:center;justify-content:center;overflow:hidden;
}
.cd-photo svg{width:46%;height:46%;color:var(--art)}
.cd-name{padding:24px var(--pad) 0}
.cd-input{
margin-top:12px;font-family:var(--serif);font-size:22px;font-weight:500;letter-spacing:-.005em;
padding:8px 0;border-bottom:.5px solid var(--hairline-2);border-radius:0;
}
.cd-input::placeholder{color:var(--ink-4)}
.cd-specs{padding-bottom:2px}
button.spec{width:100%;text-align:left;transition:background .16s var(--ease)}
button.spec:active{background:var(--fill)}
.spec-ch{width:11px;height:11px;color:var(--ink-4);flex-shrink:0;align-self:center;display:none}
[data-edit="1"] .spec-ch{display:block}
[data-edit="0"] .cd-edit-w{display:none}
[data-edit="1"] .cd-view-w{display:none}
.cd-note{
margin:14px var(--pad) 0;padding:15px 0;font-size:13.5px;line-height:1.7;color:var(--ink-2);
}
.cd-note-area{
margin:14px var(--pad) 0;padding:13px 14px;border-radius:var(--r-ctrl);background:var(--fill);
font-size:13.5px;line-height:1.7;min-height:104px;resize:none;
}
.cd-del{
display:block;width:100%;text-align:center;padding:15px 0;
font-size:14px;color:var(--ink);
text-decoration:underline;text-underline-offset:4px;
text-decoration-thickness:.5px;text-decoration-color:var(--ink-4);
}
/* 属性选择面板 */
.at-grid{display:flex;flex-wrap:wrap;gap:8px;padding:4px var(--pad) 8px}
.at-chip{
height:36px;padding:0 15px;border-radius:var(--r-pill);
font-size:13.5px;color:var(--ink-2);
box-shadow:inset 0 0 0 .5px var(--hairline-2);
display:inline-flex;align-items:center;gap:7px;
transition:background .18s var(--ease),color .18s var(--ease),box-shadow .18s var(--ease);
}
.at-chip.is-on{background:var(--ink);color:#fff;box-shadow:none}
.at-chip i{width:11px;height:11px;border-radius:50%;box-shadow:inset 0 0 0 .5px rgba(0,0,0,.16)}
.at-score{display:flex;justify-content:center;gap:14px;padding:14px var(--pad) 20px}
.at-score button{
width:38px;height:38px;border-radius:50%;font-size:13.5px;color:var(--ink-2);
box-shadow:inset 0 0 0 .5px var(--hairline-2);
display:flex;align-items:center;justify-content:center;
font-variant-numeric:tabular-nums;
transition:background .18s var(--ease),color .18s var(--ease),box-shadow .18s var(--ease);
}
.at-score button.is-on{background:var(--ink);color:#fff;box-shadow:none}
.at-field{margin:0 var(--pad) 6px;display:flex;gap:10px;align-items:center}
.at-input{
flex:1;height:42px;border-radius:var(--r-ctrl);background:var(--fill);
padding:0 13px;font-size:14px;
}
.at-input::placeholder{color:var(--ink-4)}
.at-swatches{display:grid;grid-template-columns:repeat(6,1fr);gap:10px;padding:4px var(--pad) 10px}
.at-sw{display:flex;flex-direction:column;align-items:center;gap:7px}
.at-sw i{
width:34px;height:34px;border-radius:50%;
box-shadow:inset 0 0 0 .5px rgba(0,0,0,.14);
transition:transform .18s var(--ease);
}
.at-sw span{font-size:10px;color:var(--ink-3)}
.at-sw.is-on i{transform:scale(1.06);box-shadow:inset 0 0 0 .5px rgba(0,0,0,.14),0 0 0 2px var(--paper),0 0 0 3px var(--ink)}
.at-sw.is-on span{color:var(--ink)}
/* ============================================================================
§6.9 穿搭详情
========================================================================== */
[data-screen="outfit-detail"] .scroll{padding-bottom:112px}
.od-photo{margin:16px var(--pad) 0}
.od-info{padding:24px var(--pad) 0}
.od-tags{display:flex;flex-wrap:wrap;gap:6px;margin-top:15px}
.od-desc{margin-top:17px;font-size:14px;line-height:1.8;color:var(--ink-2)}
.od-items{display:flex;gap:13px;padding:2px var(--pad) 0;overflow-x:auto}
.od-items::-webkit-scrollbar{display:none}
.od-item{width:80px;flex-shrink:0;display:flex;flex-direction:column;gap:9px;align-items:center;transition:transform .2s var(--ease)}
.od-item:active{transform:scale(.95)}
.od-item-img{width:80px;height:80px;background:var(--paper-2);border-radius:var(--r-img);display:flex;align-items:center;justify-content:center}
.od-item-img svg{width:56%;height:56%;color:var(--art)}
.od-item span{font-size:11px;color:var(--ink-2);text-align:center;line-height:1.4;width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* ============================================================================
§6.10 创建 / 编辑穿搭
========================================================================== */
[data-screen="outfit-edit"] .scroll{padding-bottom:126px}
[data-screen="outfit-edit"][data-view="select"] .scroll{padding-bottom:106px}
[data-view="select"] .oe-nav-form{display:none}
[data-view="form"] .oe-nav-select{display:none}
[data-mode="create"] .oe-only-edit{display:none}
.oe-preview{margin:20px var(--pad) 0}
.oe-empty{
aspect-ratio:4/3;border:1px dashed var(--hairline-2);border-radius:var(--r-img);
display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:0 24px;
}
.oe-empty svg{width:28px;height:28px;color:var(--ink-4);margin-bottom:16px}
.oe-empty .t{font-family:var(--serif);font-size:15px}
.oe-empty .d{margin-top:8px;font-size:11.5px;line-height:1.6;color:var(--ink-3)}
.oe-form{margin-top:32px}
.oe-field{padding:15px var(--pad);border-bottom:.5px solid var(--hairline)}
.oe-field-hd{display:flex;align-items:baseline;justify-content:space-between;gap:12px;margin-bottom:7px}
.oe-field-hd .k{font-size:12.5px;color:var(--ink-2)}
.oe-field-hd .k b{color:var(--ink);font-weight:500}
.oe-field-hd .c{font-size:11px;color:var(--ink-4);font-variant-numeric:tabular-nums}
.oe-input{font-size:15px;line-height:1.6;padding:2px 0}
.oe-input::placeholder{color:var(--ink-4)}
.oe-area{min-height:72px;resize:none;font-size:15px;line-height:1.72;padding:2px 0}
.oe-pick{
display:flex;align-items:center;gap:12px;width:100%;padding:17px var(--pad);
border-bottom:.5px solid var(--hairline);transition:background .16s var(--ease);
}
.oe-pick:active{background:var(--fill)}
.oe-pick .pk{flex:1;text-align:left;min-width:0}
.oe-pick .pk .t{font-size:15px}
.oe-pick .pk .d{margin-top:5px;font-size:11.5px;color:var(--ink-3)}
.oe-pick .pv{font-size:13px;color:var(--ink-3);font-variant-numeric:tabular-nums;flex-shrink:0}
.oe-pick .pv.is-on{color:var(--ink)}
.oe-pick svg{width:12px;height:12px;color:var(--ink-4);flex-shrink:0}
.oe-bar{
position:absolute;left:0;right:0;bottom:0;z-index:45;
padding:12px var(--pad) calc(14px + env(safe-area-inset-bottom,0px));
background:var(--glass);
-webkit-backdrop-filter:saturate(180%) blur(22px);backdrop-filter:saturate(180%) blur(22px);
border-top:.5px solid var(--hairline);
}
.oe-bar .sb{display:flex;align-items:center;gap:14px}
.oe-bar .sb-l{flex:1;min-width:0}
.oe-bar .sb-n{font-size:14px;font-variant-numeric:tabular-nums}
.oe-bar .sb-d{margin-top:3px;font-size:11px;color:var(--ink-3)}
/* ============================================================================
§6.11 AI 穿搭推荐
========================================================================== */
[data-screen="ai-recommend"] .scroll{padding-bottom:126px}
.ai-gen{display:flex;flex-direction:column;align-items:center;text-align:center;padding:168px 44px 0}
.ai-ring{width:62px;height:62px;border-radius:50%;box-shadow:inset 0 0 0 .5px var(--hairline-2);position:relative;margin-bottom:28px}
.ai-ring::before{
content:'';position:absolute;inset:-1px;border-radius:50%;
border:1px solid var(--ink);border-right-color:transparent;border-bottom-color:transparent;
animation:spin 1.5s linear infinite;
}
@keyframes spin{to{transform:rotate(360deg)}}
.ai-gen .t{font-family:var(--serif);font-size:20px;letter-spacing:-.005em}
.ai-gen .d{margin-top:10px;font-size:12.5px;color:var(--ink-3);line-height:1.7}
.ai-hint{margin-top:12px;text-align:center;font-size:11px;color:var(--ink-4)}
.scene-cards{padding:4px var(--pad) 0;display:flex;flex-direction:column;gap:10px}
.scene-card{
display:flex;align-items:center;gap:13px;width:100%;padding:15px 16px;
border-radius:var(--r-ctrl);box-shadow:inset 0 0 0 .5px var(--hairline-2);
transition:box-shadow .2s var(--ease),background .2s var(--ease);
}
.scene-card.is-on{background:var(--ink);color:#fff;box-shadow:none}
.scene-card .sc-k{flex:1;text-align:left}
.scene-card .sc-k .t{font-size:14.5px}
.scene-card .sc-k .d{margin-top:5px;font-size:11.5px;color:var(--ink-3)}
.scene-card.is-on .sc-k .d{color:rgba(255,255,255,.6)}
.scene-card .sc-ck{width:17px;height:17px;color:#fff;opacity:0}
.scene-card.is-on .sc-ck{opacity:1}
.scene-input{
margin:4px var(--pad) 0;height:46px;border-radius:var(--r-ctrl);background:var(--fill);
padding:0 15px;font-size:14px;
}
.scene-input::placeholder{color:var(--ink-4)}
/* ============================================================================
§6.12 创建衣柜分享
========================================================================== */
[data-view="select"] .csc-nav-config{display:none}
[data-view="config"] .csc-nav-select,[data-view="success"] .csc-nav-select{display:none}
[data-screen="closet-share-create"] .scroll{padding-bottom:126px}
[data-screen="closet-share-create"][data-view="select"] .scroll{padding-bottom:106px}
[data-screen="closet-share-create"][data-view="success"] .scroll{padding-bottom:132px}
[data-sharetype="2"] .csc-only-partial{display:none}
.dock .sb{display:flex;align-items:center;gap:14px}
.dock .sb-l{flex:1;min-width:0}
.dock .sb-n{font-size:14px;font-variant-numeric:tabular-nums}
.dock .sb-d{margin-top:3px;font-size:11px;color:var(--ink-3)}
.dock .cd-del{padding:11px 0 1px;font-size:13px}
.csc-opts{padding:0 var(--pad);display:flex;flex-direction:column;gap:10px}
.csc-opt{
display:flex;align-items:center;gap:13px;width:100%;padding:15px 16px;
border-radius:var(--r-ctrl);box-shadow:inset 0 0 0 .5px var(--hairline-2);
transition:box-shadow .2s var(--ease);
}
.csc-opt.is-on{box-shadow:inset 0 0 0 1.5px var(--ink)}
.csc-opt .ck{
width:19px;height:19px;border-radius:50%;flex-shrink:0;color:#fff;
display:flex;align-items:center;justify-content:center;
box-shadow:inset 0 0 0 .5px var(--hairline-2);
transition:background .2s var(--ease),box-shadow .2s var(--ease);
}
.csc-opt .ck svg{width:11px;height:11px;opacity:0;transition:opacity .2s var(--ease)}
.csc-opt.is-on .ck{background:var(--ink);box-shadow:none}
.csc-opt.is-on .ck svg{opacity:1}
.csc-opt .k{flex:1;text-align:left}
.csc-opt .k .t{display:block;font-size:14.5px}
.csc-opt .k .d{display:block;margin-top:5px;font-size:11.5px;color:var(--ink-3)}
.csc-exp{display:flex;gap:8px;padding:0 var(--pad)}
.csc-exp-item{
flex:1;height:44px;border-radius:var(--r-ctrl);font-size:13.5px;color:var(--ink-2);
box-shadow:inset 0 0 0 .5px var(--hairline-2);
display:flex;align-items:center;justify-content:center;
transition:background .2s var(--ease),color .2s var(--ease),box-shadow .2s var(--ease);
}
.csc-exp-item.is-on{background:var(--ink);color:#fff;box-shadow:none}
.csc-ok{
width:52px;height:52px;border-radius:50%;margin-bottom:20px;
box-shadow:inset 0 0 0 1px var(--hairline-2);
display:flex;align-items:center;justify-content:center;
}
.csc-ok svg{width:24px;height:24px}
.csc-preview{margin:34px var(--pad) 0;padding:18px 18px 16px;border-radius:14px;background:var(--paper-2)}
.csc-preview-hd{display:flex;align-items:center;gap:8px}
.csc-preview-hd .oav{width:22px;height:22px;border-radius:50%;background:var(--paper-3);color:var(--ink-3);display:flex;align-items:center;justify-content:center;flex-shrink:0}
.csc-preview-hd .oav svg{width:12px;height:12px}
.csc-preview-hd .tx{font-size:12.5px;color:var(--ink-2);line-height:1.4}
.csc-preview-body{
margin-top:15px;border-radius:var(--r-img);overflow:hidden;
display:grid;grid-template-columns:1fr 1fr;grid-template-rows:1fr 1fr;gap:1px;background:var(--paper-3);
}
.csc-preview-body .c{aspect-ratio:1/1;background:var(--paper);display:flex;align-items:center;justify-content:center;min-width:0;min-height:0;overflow:hidden}
.csc-preview-body .c svg{width:48px;height:48px;flex-shrink:0;color:var(--art)}
/* ============================================================================
§6.13 分享详情(衣柜 / 穿搭)
========================================================================== */
[data-screen="closet-share-detail"] .scroll,
[data-screen="outfit-share-detail"] .scroll{padding-bottom:140px}
.sd-owner{display:flex;align-items:center;gap:13px;padding:24px var(--pad) 0}
.sd-av{
width:46px;height:46px;border-radius:50%;flex-shrink:0;overflow:hidden;
background:var(--paper-3);color:var(--ink-3);
display:flex;align-items:center;justify-content:center;
}
.sd-av svg{width:22px;height:22px}
.sd-t{font-family:var(--serif);font-size:15.5px;line-height:1.4;letter-spacing:-.003em}
.sd-d{margin-top:6px;font-size:11.5px;color:var(--ink-3);font-variant-numeric:tabular-nums}
/* 胶囊语义变体(零彩色状态系统) */
.pill--ring{background:transparent;box-shadow:inset 0 0 0 .5px var(--ink);color:var(--ink)}
.pill--mute{background:var(--fill);color:var(--ink-3)}
.pill--faint{background:transparent;box-shadow:inset 0 0 0 .5px var(--hairline-2);color:var(--ink-2)}
/* ============================================================================
§6.14 通知列表 / 通知详情
========================================================================== */
.nt-list{padding:10px var(--pad) 0}
.nt-item{
position:relative;display:flex;gap:13px;width:100%;padding:16px 0 16px 13px;
border-bottom:.5px solid var(--hairline);align-items:flex-start;text-align:left;
transition:opacity .2s var(--ease);
}
.nt-item:active{opacity:.55}
.nt-item.is-unread::after{
content:'';position:absolute;left:0;top:19px;bottom:19px;width:2.5px;
border-radius:2px;background:var(--ink);
}
.nt-ic{
width:34px;height:34px;border-radius:50%;flex-shrink:0;
background:var(--paper-2);color:var(--ink-3);
display:flex;align-items:center;justify-content:center;
}
.nt-ic svg{width:16px;height:16px}
.nt-body{flex:1;min-width:0}
.nt-t{font-size:14.5px;font-weight:500;line-height:1.42;color:var(--ink-3)}
.nt-c{
margin-top:6px;font-size:12.5px;line-height:1.62;color:var(--ink-3);
display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
.nt-time{margin-top:9px;font-size:11px;color:var(--ink-4);font-variant-numeric:tabular-nums}
.nt-item.is-unread .nt-t{color:var(--ink)}
.nt-item.is-unread .nt-c{color:var(--ink-2)}
.nd-card{padding:26px var(--pad) 0}
.nd-ic{
width:38px;height:38px;border-radius:50%;background:var(--paper-2);color:var(--ink-3);
display:flex;align-items:center;justify-content:center;margin-bottom:22px;
}
.nd-ic svg{width:18px;height:18px}
.nd-time{margin-top:13px;font-size:11.5px;color:var(--ink-3);font-variant-numeric:tabular-nums}
.nd-body{margin-top:28px;padding-top:26px;border-top:.5px solid var(--hairline);font-size:14.5px;line-height:1.92;color:var(--ink-2)}
/* ============================================================================
§6.15 额度与会员商城
========================================================================== */
[data-screen="mall"] .scroll{padding-bottom:56px}
.ml-vip{margin:26px var(--pad) 0;padding:20px 20px 18px;border-radius:14px;background:var(--block);color:#fff}
.ml-vip-top{display:flex;align-items:flex-start;gap:12px}
.ml-vip-top svg{width:21px;height:21px;flex-shrink:0;margin-top:2px;opacity:.92}
.ml-vip-t{font-family:var(--serif);font-size:18px;font-weight:500;letter-spacing:-.005em}
.ml-vip-d{margin-top:7px;font-size:11.5px;line-height:1.62;color:rgba(255,255,255,.55)}
.ml-vip-btn{
margin-top:18px;display:flex;width:100%;height:42px;border-radius:var(--r-pill);
background:#fff;color:var(--ink);align-items:center;justify-content:center;
font-size:14px;font-weight:500;transition:transform .18s var(--ease),opacity .18s var(--ease);
}
.ml-vip-btn:active{transform:scale(.975);opacity:.8}
.ml-quota{margin-top:30px}
.ml-entry{
display:flex;align-items:center;gap:10px;width:100%;padding:16px var(--pad);
border-top:.5px solid var(--hairline);border-bottom:.5px solid var(--hairline);
transition:background .16s var(--ease);
}
.ml-entry:active{background:var(--fill)}
.ml-entry .t{flex:1;text-align:left;font-size:14.5px}
.ml-entry svg{width:12px;height:12px;color:var(--ink-4)}
.ml-goods{padding:10px var(--pad) 0}
.ml-good{display:flex;align-items:center;gap:13px;width:100%;padding:17px 0;border-bottom:.5px solid var(--hairline)}
.ml-good-ic{
width:40px;height:40px;border-radius:50%;flex-shrink:0;
background:var(--paper-2);color:var(--ink-2);
display:flex;align-items:center;justify-content:center;
}
.ml-good-ic svg{width:18px;height:18px}
.ml-good-b{flex:1;min-width:0;text-align:left}
.ml-good-n{font-size:14.5px;line-height:1.4}
.ml-good-d{margin-top:6px;font-size:11.5px;line-height:1.6;color:var(--ink-3)}
.ml-price{display:flex;align-items:baseline;gap:8px;margin-top:9px}
.ml-price .now{font-family:var(--serif);font-size:17px;font-weight:500;font-variant-numeric:tabular-nums}
.ml-price .old{font-size:11.5px;color:var(--ink-4);text-decoration:line-through;font-variant-numeric:tabular-nums}
.ml-flow{padding:6px var(--pad) 0}
.fl-row{display:flex;align-items:flex-start;gap:14px;padding:15px 0;border-bottom:.5px solid var(--hairline)}
.fl-l{flex:1;min-width:0}
.fl-r{font-size:14px;line-height:1.4}
.fl-t{margin-top:6px;font-size:11px;color:var(--ink-3);font-variant-numeric:tabular-nums}
.fl-v{text-align:right;flex-shrink:0}
.fl-n{font-family:var(--serif);font-size:16px;font-variant-numeric:tabular-nums}
.fl-n.is-down{color:var(--ink-2)}
.fl-s{margin-top:6px;font-size:11px;color:var(--ink-4);font-variant-numeric:tabular-nums}
.ml-back{
display:block;padding:22px var(--pad) 4px;font-size:13px;color:var(--ink-2);text-align:left;
}
/* ============================================================================
§6.16 我的订单
========================================================================== */
.or-list{padding:14px var(--pad) 0;display:flex;flex-direction:column}
.or-card{padding:17px 0;border-bottom:.5px solid var(--hairline)}
.or-top{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.or-no{font-size:11px;color:var(--ink-3);letter-spacing:.04em;font-variant-numeric:tabular-nums}
.or-name{margin-top:13px;font-family:var(--serif);font-size:16px;font-weight:500;line-height:1.35}
.or-benefit{margin-top:7px;font-size:11.5px;color:var(--ink-3)}
.or-bot{display:flex;align-items:center;gap:13px;margin-top:16px;flex-wrap:wrap}
.or-amt{font-size:12.5px;color:var(--ink-2)}
.or-amt b{font-family:var(--serif);font-size:17px;font-weight:500;color:var(--ink);margin-left:5px;font-variant-numeric:tabular-nums}
.or-cd{font-size:11.5px;color:var(--ink-2);font-variant-numeric:tabular-nums;letter-spacing:.04em}
/* ============================================================================
§6.17 设计规范
========================================================================== */
.sp-sec{padding:34px var(--pad) 0}
.sp-swatches{display:flex;flex-wrap:wrap;gap:14px}
.sp-sw{width:64px}
.sp-sw i{display:block;width:64px;height:44px;border-radius:6px;box-shadow:inset 0 0 0 .5px rgba(0,0,0,.1)}
.sp-sw .n{margin-top:8px;font-size:10.5px;color:var(--ink-2)}
.sp-sw .h{margin-top:2px;font-size:9.5px;color:var(--ink-4);letter-spacing:.04em}
.sp-rows{display:flex;flex-direction:column;gap:18px;margin-top:18px}
.sp-row{display:flex;align-items:baseline;gap:14px}
.sp-row .meta{width:78px;flex-shrink:0;font-size:9.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-4)}
.sp-row .demo{flex:1;min-width:0}
.sp-btns{display:flex;flex-wrap:wrap;gap:10px;margin-top:16px}
.sp-glass{
margin-top:16px;padding:18px;border-radius:14px;background:var(--glass);
-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);
border:.5px solid rgba(255,255,255,.7);
background-image:linear-gradient(120deg,#EFEFED,#F7F7F5 40%,#E4E4E1);
font-size:12.5px;color:var(--ink-2);line-height:1.7;
}
.sp-meter{display:flex;flex-direction:column;gap:12px;margin-top:16px}
.sp-meter .r{display:flex;align-items:center;gap:12px;font-size:11.5px;color:var(--ink-2)}
.sp-meter .r b{width:70px;flex-shrink:0;font-weight:500}
/* ==PAGE-CSS== */
</style>
</head>
<body>
<!-- ===================== SVG 图标与衣物线稿 ===================== -->
<svg width="0" height="0" style="position:absolute" aria-hidden="true">
<defs>
<symbol id="i-hanger" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
<path d="M12 3.4a2.1 2.1 0 1 1 2.1 2.1c-1.16 0-2.1.94-2.1 2.1v1.1"/>
<path d="M12 8.7 3.5 14.5a1.7 1.7 0 0 0 .95 3.1h15.1a1.7 1.7 0 0 0 .95-3.1L12 8.7Z"/>
</symbol>
<symbol id="i-shirt" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
<path d="M16 3l4 4-2 2-1-1v3l2 2v6a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2v-6l2-2V8L6 9 4 7l4-4h2a2 2 0 0 0 4 0h2z"/>
</symbol>
<symbol id="i-sparkles" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
<path d="M12 3l1.9 5.1L19 10l-5.1 1.9L12 17l-1.9-5.1L5 10l5.1-1.9L12 3z"/>
</symbol>
<symbol id="i-bell" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
<path d="M18 8a6 6 0 0 0-12 0c0 7-3 9-3 9h18s-3-2-3-9"/>
<path d="M13.73 21a2 2 0 0 1-3.46 0"/>
</symbol>
<symbol id="i-user" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/>
</symbol>
<symbol id="i-plus" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
<path d="M12 5v14"/><path d="M5 12h14"/>
</symbol>
<symbol id="i-chev-r" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
<path d="M9 18l6-6-6-6"/>
</symbol>
<symbol id="i-chev-l" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round">
<path d="M15 18l-6-6 6-6"/>
</symbol>
<symbol id="i-camera" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
<path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/>
<circle cx="12" cy="13" r="4"/>
</symbol>
<symbol id="i-heart" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
<path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/>
</symbol>
<symbol id="i-heart-f" viewBox="0 0 24 24" fill="currentColor">
<path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/>
</symbol>
<symbol id="i-star" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
<path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/>
</symbol>
<symbol id="i-star-f" viewBox="0 0 24 24" fill="currentColor">
<path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/>
</symbol>
<symbol id="i-share" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
<circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/>
<path d="M8.59 13.51l6.83 3.98"/><path d="M15.41 6.51l-6.82 3.98"/>
</symbol>
<symbol id="i-trash" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
<path d="M3 6h18"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6"/>
<path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/>
</symbol>
<symbol id="i-pencil" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
<path d="M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z"/>
</symbol>
<symbol id="i-crown" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
<path d="M3 8l4 4 5-6 5 6 4-4-2 9H5L3 8z"/>
</symbol>
<symbol id="i-doc" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
<path d="M14 2v6h6"/><path d="M16 13H8"/><path d="M16 17H8"/>
</symbol>
<symbol id="i-gauge" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="9"/><path d="M12 12l5-3"/>
</symbol>
<symbol id="i-check" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round">
<path d="M20 6L9 17l-5-5"/>
</symbol>
<symbol id="i-close" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round">
<path d="M18 6L6 18"/><path d="M6 6l12 12"/>
</symbol>
<symbol id="i-ellipsis" viewBox="0 0 24 24" fill="currentColor">
<circle cx="12" cy="5" r="1.9"/><circle cx="12" cy="12" r="1.9"/><circle cx="12" cy="19" r="1.9"/>
</symbol>
<symbol id="i-calendar" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
<rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4"/><path d="M8 2v4"/><path d="M3 10h18"/>
</symbol>
<symbol id="i-headphones" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
<path d="M3 18v-6a9 9 0 0 1 18 0v6"/>
<path d="M21 19a2 2 0 0 1-2 2h-1a2 2 0 0 1-2-2v-3a2 2 0 0 1 2-2h3zM3 19a2 2 0 0 0 2 2h1a2 2 0 0 0 2-2v-3a2 2 0 0 0-2-2H3z"/>
</symbol>
<symbol id="i-info" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/>
</symbol>
<symbol id="i-search" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
<circle cx="11" cy="11" r="7"/><path d="M20 20l-3.6-3.6"/>
</symbol>
<symbol id="i-wechat" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
<path d="M9.2 3.6C5.3 3.6 2.2 6.2 2.2 9.4c0 1.8 1 3.4 2.5 4.5L4 16.6l2.7-1.3c.8.2 1.6.3 2.5.3"/>
<path d="M14.8 8.6c3.9 0 7 2.4 7 5.4 0 1.6-.9 3.1-2.3 4l.5 2.4-2.5-1.2c-.9.2-1.8.3-2.7.3-3.9 0-7-2.4-7-5.5s3.1-5.4 7-5.4Z"/>
</symbol>
<symbol id="i-image" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
<rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="8.5" cy="8.5" r="1.6"/><path d="M21 15l-5-5L5 21"/>
</symbol>
<!-- 衣物线稿(买手店目录质感) -->
<symbol id="g-shirt" viewBox="0 0 100 100" fill="none" stroke="currentColor" stroke-width="1.3" stroke-linejoin="round" stroke-linecap="round">
<path d="M37 20 25 26 19 40l10 4.6 3.4-7.2V82h35.2V37.4l3.4 7.2 10-4.6-6-14-12-6"/>
<path d="M37 20c1.4 4.6 6.2 7.2 13 7.2S61.6 24.6 63 20"/>
</symbol>
<symbol id="g-pants" viewBox="0 0 100 100" fill="none" stroke="currentColor" stroke-width="1.3" stroke-linejoin="round" stroke-linecap="round">
<path d="M30 19h40l3.4 63H59.6L50 47.4 40.4 82H26.6L30 19Z"/>
<path d="M30 27h40"/>
</symbol>
<symbol id="g-dress" viewBox="0 0 100 100" fill="none" stroke="currentColor" stroke-width="1.3" stroke-linejoin="round" stroke-linecap="round">
<path d="M40 18 29 26.4l5.6 7.6 4.8-3.2L30 82h40l-9.4-51.2 4.8 3.2 5.6-7.6L60 18"/>
<path d="M40 18c1.4 3.2 4.6 5 10 5s8.6-1.8 10-5"/>
<path d="M37 48h26"/>
</symbol>
<symbol id="g-coat" viewBox="0 0 100 100" fill="none" stroke="currentColor" stroke-width="1.3" stroke-linejoin="round" stroke-linecap="round">
<path d="M38 19 24 25.6 18 45l10.6 4 2.8-6.4V82h37.2V42.6l2.8 6.4L82 45l-6-19.4L62 19l-6 10.4h-12L38 19Z"/>
<path d="M50 29.4V82"/>
<path d="M56 40h7M56 52h7"/>
</symbol>
<symbol id="g-shoe" viewBox="0 0 100 100" fill="none" stroke="currentColor" stroke-width="1.3" stroke-linejoin="round" stroke-linecap="round">
<path d="M15 68c0-5.4 2.4-9.6 7.4-11.6l9.6-3.6 5.4 5.4 11 3.2 18 4.6c7.4 2 12.6 5.4 12.6 10.4V80H15V68Z"/>
<path d="M15 72.6h64"/>
<path d="M32 52.8l4.6 6.6"/>
</symbol>
<symbol id="g-bag" viewBox="0 0 100 100" fill="none" stroke="currentColor" stroke-width="1.3" stroke-linejoin="round" stroke-linecap="round">
<path d="M27 37h46l4.6 44H22.4L27 37Z"/>
<path d="M38 37V28a12 12 0 0 1 24 0v9"/>
</symbol>
<symbol id="g-sweater" viewBox="0 0 100 100" fill="none" stroke="currentColor" stroke-width="1.3" stroke-linejoin="round" stroke-linecap="round">
<path d="M38 20 22 27l-5 15 10.6 4 3.4-6.4V82h38V39.6l3.4 6.4L83 42l-5-15-16-7"/>
<path d="M38 20c1.4 4.4 6.2 7 12 7s10.6-2.6 12-7"/>
<path d="M34 44h32M34 58h32M34 72h32"/>
</symbol>
</defs>
</svg>
<!-- ===================== 工作台 ===================== -->
<div class="wb">
<aside class="wb-index">
<div class="wb-brand">
<div class="eyebrow">UI Redesign · V2</div>
<h1 class="wb-title">纸条 AI 衣橱</h1>
<p class="wb-sub">苹果简约高级 · 零彩色灰阶 · 毛玻璃浮层</p>
</div>
<nav class="wb-nav" id="wbIndex"></nav>
<div class="wb-foot">19 屏 · 单文件交互原型 · 无外部依赖</div>
</aside>
<div class="wb-stage">
<div class="device">
<div class="island"></div>
<div class="statusbar">
<span class="sb-time num">9:41</span>
<span class="sb-right">
<svg class="sb-ic" viewBox="0 0 18 12"><rect x="0" y="8" width="3" height="4" rx="1"/><rect x="5" y="5.6" width="3" height="6.4" rx="1"/><rect x="10" y="3.2" width="3" height="8.8" rx="1"/><rect x="15" y="0.8" width="3" height="11.2" rx="1"/></svg>
<svg class="sb-ic" viewBox="0 0 16 12" style="height:10.5px"><path d="M8 11.2 5.9 8.9a3 3 0 0 1 4.2 0L8 11.2Z"/><path d="M8 7.2a5.6 5.6 0 0 0-3.9 1.6L2.6 7.3a7.7 7.7 0 0 1 10.8 0l-1.5 1.5A5.6 5.6 0 0 0 8 7.2Z"/><path d="M8 3.2a9.6 9.6 0 0 0-6.7 2.7L0 4.6a11.7 11.7 0 0 1 16 0l-1.3 1.3A9.6 9.6 0 0 0 8 3.2Z"/></svg>
<svg class="sb-bat" viewBox="0 0 26 12"><rect x="0.5" y="0.5" width="21" height="11" rx="3.4" fill="none" stroke="currentColor" stroke-width="1" opacity=".38"/><rect x="2.2" y="2.2" width="16.6" height="7.6" rx="2.2"/><path d="M23.4 4.2v3.6a2 2 0 0 0 0-3.6Z" opacity=".38"/></svg>
</span>
</div>
<div class="capsule">
<svg width="17" height="9" viewBox="0 0 17 9" fill="currentColor"><circle cx="3" cy="4.5" r="1.6"/><circle cx="8.5" cy="4.5" r="1.6"/><circle cx="14" cy="4.5" r="1.6"/></svg>
<span class="cap-div"></span>
<svg width="15" height="15" viewBox="0 0 18 18" fill="none"><circle cx="9" cy="9" r="7.2" stroke="currentColor" stroke-width="1.5"/><circle cx="9" cy="9" r="2.5" fill="currentColor"/></svg>
</div>
<main id="app">
<!-- ============ 登录 ============ -->
<section class="screen" data-screen="login" data-state="idle" data-states="idle,submitting">
<div class="scroll">
<div class="lg-top">
<div class="lg-hero">
<svg class="lg-ic1"><use href="#i-hanger"/></svg>
<svg class="lg-ic2"><use href="#i-shirt"/></svg>
<svg class="lg-ic3"><use href="#i-sparkles"/></svg>
<svg class="lg-ic4"><use href="#i-camera"/></svg>
<svg class="lg-ic5"><use href="#i-star"/></svg>
</div>
<div class="lg-logo"><svg><use href="#i-hanger"/></svg></div>
<h1 class="lg-name">纸条AI衣橱</h1>
<p class="lg-slogan">把你的衣橱,交给 AI 打理</p>
</div>
<div class="lg-foot">
<div class="st" data-when="idle">
<button class="btn btn--ink btn--block" data-modal="gift">
<svg><use href="#i-wechat"/></svg><span>微信一键登录</span>
</button>
</div>
<div class="st" data-when="submitting">
<button class="btn btn--ink btn--block is-off">
<svg><use href="#i-wechat"/></svg><span>登录中…</span>
</button>
</div>
<p class="lg-terms">登录即代表同意<a data-toast="协议内容敬请期待">《用户协议》</a>和<a data-toast="协议内容敬请期待">《隐私政策》</a></p>
</div>
</div>
</section>
<!-- ============ 衣橱 ============ -->
<section class="screen" data-screen="wardrobe" data-tab="0" data-state="list" data-states="list,skeleton,empty">
<div class="nav" data-nav="large">
<div class="nav-inner"></div>
<div class="nav-title">我的衣橱</div>
</div>
<div class="scroll">
<div class="head">
<div class="eyebrow">Wardrobe</div>
<h1 class="display">我的衣橱</h1>
<div class="wd-stat num">共 24 件 · 上传额度剩余 3 次</div>
</div>
<div class="segbar" style="margin-top:18px">
<div class="seg">
<button class="seg-item is-on">全部</button>
<button class="seg-item">上装</button>
<button class="seg-item">下装</button>
<button class="seg-item">连衣裙</button>
<button class="seg-item">外套</button>
<button class="seg-item">鞋</button>
<button class="seg-item">配饰</button>
</div>
</div>
<div class="st" data-when="skeleton">
<div class="wd-skel">
<div><div class="sk sk-img"></div><div class="sk sk-ln" style="width:70%"></div><div class="sk sk-ln" style="width:46%"></div></div>
<div><div class="sk sk-img"></div><div class="sk sk-ln" style="width:62%"></div><div class="sk sk-ln" style="width:40%"></div></div>
<div><div class="sk sk-img"></div><div class="sk sk-ln" style="width:74%"></div><div class="sk sk-ln" style="width:52%"></div></div>
<div><div class="sk sk-img"></div><div class="sk sk-ln" style="width:58%"></div><div class="sk sk-ln" style="width:38%"></div></div>
<div><div class="sk sk-img"></div><div class="sk sk-ln" style="width:68%"></div><div class="sk sk-ln" style="width:44%"></div></div>
<div><div class="sk sk-img"></div><div class="sk sk-ln" style="width:64%"></div><div class="sk sk-ln" style="width:50%"></div></div>
</div>
</div>
<div class="st" data-when="empty">
<div class="empty">
<svg class="empty-ic"><use href="#i-hanger"/></svg>
<div class="empty-t">衣橱还空着</div>
<div class="empty-d">拍照上传第一件衣物,AI 自动抠图并识别属性</div>
<button class="btn btn--ink empty-b" data-nav="upload">上传衣物</button>
</div>
</div>
<div class="st" data-when="list">
<div class="wd-grid">
<button class="wd-tile" data-nav="clothes-detail" data-params='{"uuid":"c1"}'>
<div class="tile-img"><svg><use href="#g-shirt"/></svg></div>
<div class="tile-name">白色棉质衬衫</div>
<div class="tile-sub">上装 · 衬衫 · 白色</div>
</button>
<button class="wd-tile" data-nav="clothes-detail" data-params='{"uuid":"c2"}'>
<div class="tile-img"><svg><use href="#g-pants"/></svg></div>
<div class="tile-name">高腰阔腿西裤</div>
<div class="tile-sub">下装 · 长裤 · 黑色</div>
</button>
<button class="wd-tile" data-nav="clothes-detail" data-params='{"uuid":"c3"}'>
<div class="tile-img"><svg><use href="#g-sweater"/></svg></div>
<div class="tile-name">米色针织开衫</div>
<div class="tile-sub">上装 · 针织衫 · 米色</div>
</button>
<button class="wd-tile" data-nav="clothes-detail" data-params='{"uuid":"c4"}'>
<div class="tile-img"><svg><use href="#g-dress"/></svg></div>
<div class="tile-name">黑色吊带连衣裙</div>
<div class="tile-sub">连衣裙 · 吊带裙 · 黑色</div>
</button>
<button class="wd-tile" data-nav="clothes-detail" data-params='{"uuid":"c5"}'>
<div class="tile-img"><svg><use href="#g-coat"/></svg></div>
<div class="tile-name">驼色羊绒大衣</div>
<div class="tile-sub">外套 · 大衣 · 棕色</div>
</button>
<button class="wd-tile" data-nav="clothes-detail" data-params='{"uuid":"c6"}'>
<div class="tile-img"><svg><use href="#g-shoe"/></svg></div>
<div class="tile-name">白色真皮小白鞋</div>
<div class="tile-sub">鞋 · 板鞋 · 白色</div>
</button>
<button class="wd-tile" data-nav="clothes-detail" data-params='{"uuid":"c7"}'>
<div class="tile-img"><svg><use href="#g-bag"/></svg></div>
<div class="tile-name">深棕通勤托特包</div>
<div class="tile-sub">配饰 · 包袋 · 棕色</div>
</button>
<button class="wd-tile" data-nav="clothes-detail" data-params='{"uuid":"c8"}'>
<div class="tile-img is-empty">
<span class="tile-flag">AI 处理中</span>
<svg><use href="#i-hanger"/></svg>
</div>
<div class="tile-name">未命名衣物</div>
<div class="tile-sub">&nbsp;</div>
</button>
</div>
<div class="foot-note">没有更多了</div>
</div>
</div>
<button class="fab" data-nav="upload"><svg><use href="#i-plus"/></svg></button>
</section>
<!-- ============ 穿搭 ============ -->
<section class="screen" data-screen="outfit" data-tab="1" data-seg="0" data-state="list" data-states="list,skeleton,empty">
<div class="nav" data-nav="large">
<div class="nav-inner"></div>
<div class="nav-title">穿搭</div>
</div>
<div class="scroll">
<div class="head">
<div class="eyebrow">Styling</div>
<h1 class="display">穿搭</h1>
</div>
<div class="segbar" style="margin-top:18px">
<div class="seg">
<button class="seg-item is-on" data-seg-to="0">我的穿搭</button>
<button class="seg-item" data-seg-to="1">已收藏</button>
<button class="seg-item" data-seg-to="2">社区</button>
</div>
</div>
<div class="st" data-when="skeleton">
<div class="of-skel">
<div><div class="sk sk-img" style="aspect-ratio:4/3"></div><div class="sk sk-ln" style="width:44%"></div><div class="sk sk-ln" style="width:72%"></div></div>
<div><div class="sk sk-img" style="aspect-ratio:4/3"></div><div class="sk sk-ln" style="width:52%"></div><div class="sk sk-ln" style="width:64%"></div></div>
</div>
</div>
<div class="st" data-when="empty">
<div class="empty">
<svg class="empty-ic"><use href="#i-shirt"/></svg>
<div class="empty-t of-empty-t">还没有穿搭</div>
<div class="empty-d of-empty-d">从衣橱挑几件,搭一套吧</div>
<button class="btn btn--ink empty-b of-empty-b" data-nav="outfit-edit">创建穿搭</button>
</div>
</div>
<div class="st" data-when="list">
<div class="of-list">
<button class="of-card seg-c0" data-nav="outfit-detail" data-params='{"uuid":"o1","owner":"1"}'>
<div class="collage" data-n="3">
<div class="cg"><svg><use href="#g-shirt"/></svg></div>
<div class="cg"><svg><use href="#g-pants"/></svg></div>
<div class="cg"><svg><use href="#g-bag"/></svg></div>
<span class="cg-badge">3 件</span>
</div>
<div class="of-trow">
<span class="of-title">周末咖啡散步</span>
<span class="pill">仅自己可见</span>
</div>
<div class="of-desc">白衬衫配阔腿西裤,松弛又利落。包袋选深棕,压住整体的轻飘感。</div>
<div class="of-meta">
<span class="pill pill--line">休闲</span>
<span class="m">3 件衣物</span>
<span class="spacer"></span>
<span class="m"><svg><use href="#i-heart"/></svg><span class="num">12</span></span>
</div>
</button>
<button class="of-card seg-c0" data-nav="outfit-detail" data-params='{"uuid":"o2","owner":"1"}'>
<div class="collage" data-n="4">
<div class="cg"><svg><use href="#g-coat"/></svg></div>
<div class="cg"><svg><use href="#g-sweater"/></svg></div>
<div class="cg"><svg><use href="#g-pants"/></svg></div>
<div class="cg"><svg><use href="#g-shoe"/></svg></div>
<span class="cg-badge">4 件</span>
</div>
<div class="of-trow">
<span class="of-title">通勤极简三件套</span>
<span class="pill pill--ring">已公开</span>
</div>
<div class="of-desc">驼色大衣打底,针织开衫做层次,配西裤与小白鞋,开会与通勤都撑得住。</div>
<div class="of-meta">
<span class="pill pill--line">通勤</span>
<span class="m">4 件衣物</span>
<span class="spacer"></span>
<span class="m"><svg><use href="#i-heart"/></svg><span class="num">28</span></span>
</div>
</button>
<button class="of-card seg-c1" data-nav="outfit-detail" data-params='{"uuid":"o4","owner":"0"}'>
<div class="of-author">
<span class="of-av"><svg><use href="#i-user"/></svg></span>
<span class="of-aname">陈屿</span>
<span class="of-atime">昨天</span>
</div>
<div class="collage" data-n="2">
<div class="cg"><svg><use href="#g-sweater"/></svg></div>
<div class="cg"><svg><use href="#g-pants"/></svg></div>
<span class="cg-badge">2 件</span>
</div>
<div class="of-trow"><span class="of-title">极简黑白通勤</span></div>
<div class="of-desc">只用黑白灰三色,针织开衫配直筒西裤,把注意力全部留给剪裁本身。</div>
<div class="of-meta">
<span class="pill pill--line">通勤</span>
<span class="m">2 件衣物</span>
<span class="spacer"></span>
<span class="m"><svg><use href="#i-heart"/></svg><span class="num">76</span></span>
<span class="m"><svg><use href="#i-star-f"/></svg><span class="num">12</span></span>
</div>
</button>
<button class="of-card seg-c2" data-nav="outfit-detail" data-params='{"uuid":"o3","owner":"0"}'>
<div class="of-author">
<span class="of-av"><svg><use href="#i-user"/></svg></span>
<span class="of-aname">林小满</span>
<span class="of-atime">2 小时前</span>
</div>
<div class="collage" data-n="4">
<div class="cg"><svg><use href="#g-dress"/></svg></div>
<div class="cg"><svg><use href="#g-coat"/></svg></div>
<div class="cg"><svg><use href="#g-bag"/></svg></div>
<div class="cg"><svg><use href="#g-shoe"/></svg></div>
<span class="cg-badge">5 件</span>
</div>
<div class="of-trow">
<span class="of-title">秋日法式复古</span>
</div>
<div class="of-desc">吊带连衣裙叠穿羊绒大衣,托特包与小白鞋收尾,安静但很有存在感。</div>
<div class="of-meta">
<span class="pill pill--line">约会</span>
<span class="m">5 件衣物</span>
<span class="spacer"></span>
<span class="m"><svg><use href="#i-heart"/></svg><span class="num">128</span></span>
<span class="m"><svg><use href="#i-star"/></svg><span class="num">34</span></span>
</div>
</button>
</div>
<div class="foot-note">没有更多了</div>
</div>
</div>
<div class="float-duo of-hide-community">
<button class="btn btn--ghost" data-nav="outfit-edit">创建穿搭</button>
<button class="btn btn--ink" data-nav="ai-recommend">AI 推荐</button>
</div>
</section>
<!-- ============ 运势 ============ -->
<section class="screen" data-screen="horoscope" data-tab="2" data-state="list" data-states="list,skeleton,error,empty">
<div class="nav" data-nav="large">
<div class="nav-inner"></div>
<div class="nav-title">每日运势</div>
<button class="nav-action" style="position:absolute;right:104px;top:var(--status-h);height:var(--nav-h);display:flex;align-items:center" data-nav="profile">去设置生日</button>
</div>
<div class="scroll">
<div class="head">
<div class="eyebrow">Daily Fortune</div>
<h1 class="display">每日运势</h1>
</div>
<div class="st" data-when="skeleton">
<div style="padding:30px var(--pad) 0;display:flex;flex-direction:column;gap:22px">
<div class="sk sk-ln" style="width:38%;height:14px"></div>
<div class="sk" style="width:56%;height:64px;border-radius:6px"></div>
<div class="sk sk-ln" style="width:100%;height:9px"></div>
<div class="sk sk-ln" style="width:100%;height:9px"></div>
<div class="sk sk-ln" style="width:100%;height:9px"></div>
<div class="sk sk-ln" style="width:92%;height:9px"></div>
<div class="sk sk-ln" style="width:84%;height:9px"></div>
</div>
</div>
<div class="st" data-when="empty">
<div class="empty">
<svg class="empty-ic"><use href="#i-calendar"/></svg>
<div class="empty-t">还没有设置生日</div>
<div class="empty-d">设置生日后即可查看你的星座运势</div>
<button class="btn btn--ink empty-b" data-nav="profile">去完善资料</button>
</div>
</div>
<div class="st" data-when="error">
<div class="empty">
<svg class="empty-ic"><use href="#i-sparkles"/></svg>
<div class="empty-t">运势加载失败</div>
<div class="empty-d">运势加载失败,请重试</div>
<button class="btn btn--ink empty-b">重试</button>
</div>
</div>
<div class="st" data-when="list">
<div class="hs-hero">
<div class="hs-zodiac">
<svg><use href="#i-sparkles"/></svg>
<span class="t-xl">天秤座</span>
</div>
<div class="hs-date">2026.09.15</div>
</div>
<div class="hs-score">
<div>
<div class="eyebrow">综合运势</div>
<div class="hs-num" style="margin-top:12px">8.0</div>
</div>
<div class="hs-stars">
<svg><use href="#i-star-f"/></svg>
<svg><use href="#i-star-f"/></svg>
<svg><use href="#i-star-f"/></svg>
<svg><use href="#i-star-f"/></svg>
<svg style="color:var(--ink-4)"><use href="#i-star"/></svg>
</div>
</div>
<div class="hs-scales">
<div>
<div class="hs-st"><span class="k">爱情运势</span><span class="v num">4/5</span></div>
<div class="scale">
<div class="scale-ticks"><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i></div>
<div class="scale-line"></div>
<div class="scale-fill" style="width:80%"></div>
<div class="scale-pip" style="left:80%"></div>
</div>
</div>
<div>
<div class="hs-st"><span class="k">工作运势</span><span class="v num">5/5</span></div>
<div class="scale">
<div class="scale-ticks"><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i></div>
<div class="scale-line"></div>
<div class="scale-fill" style="width:100%"></div>
<div class="scale-pip" style="left:100%"></div>
</div>
</div>
<div>
<div class="hs-st"><span class="k">财富运势</span><span class="v num">3/5</span></div>
<div class="scale">
<div class="scale-ticks"><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i></div>
<div class="scale-line"></div>
<div class="scale-fill" style="width:60%"></div>
<div class="scale-pip" style="left:60%"></div>
</div>
</div>
</div>
<div class="hs-quote">
<div class="eyebrow">今日运势</div>
<p class="qt">今天的你在人群中格外松弛,适合把积压的社交邀约一次性兑现。工作上不必急于表态,先听完再回应,会有人替你说话。财运平平,但一件早就想买的基础款值得出手。</p>
</div>
<div class="hs-lucky">
<div>
<div class="lk">幸运色</div>
<div class="lv"><i style="background:#FF2D55"></i>粉色</div>
</div>
<div>
<div class="lk">幸运数字</div>
<div class="lv num">7</div>
</div>
</div>
<div class="pad" style="padding-top:30px">
<button class="btn btn--ghost btn--block" data-nav="ai-recommend">生成今日推荐穿搭</button>
</div>
</div>
</div>
</section>
<!-- ============ 分享列表 ============ -->
<section class="screen" data-screen="closet-share" data-tab="3" data-seg="0" data-state="list" data-states="list,empty">
<div class="nav" data-nav="large">
<div class="nav-inner"></div>
<div class="nav-title">分享</div>
<button class="nav-action nav-action--ink" style="position:absolute;right:104px;top:var(--status-h);height:var(--nav-h);display:flex;align-items:center" data-nav="closet-share-create">新建</button>
</div>
<div class="scroll">
<div class="head">
<div class="eyebrow">Sharing</div>
<h1 class="display">分享</h1>
</div>
<div class="segbar" style="margin-top:18px">
<div class="seg">
<button class="seg-item is-on" data-seg-to="0">我的分享</button>
<button class="seg-item" data-seg-to="1">分享给我的</button>
</div>
</div>
<div class="st" data-when="empty">
<div class="empty">
<svg class="empty-ic"><use href="#i-share"/></svg>
<div class="empty-t of-empty-t">还没有分享</div>
<div class="empty-d of-empty-d">把衣橱或精选衣物分享给好友</div>
<button class="btn btn--ink empty-b of-empty-b" data-nav="closet-share-create">新建分享</button>
</div>
</div>
<div class="st" data-when="list">
<div class="cs-list">
<button class="cs-card seg-c0" data-nav="closet-share-detail" data-params='{"uuid":"s1"}'>
<div class="cs-thumb">
<span class="c"><svg><use href="#i-hanger"/></svg></span>
<span class="c"><svg><use href="#i-hanger"/></svg></span>
<span class="c"><svg><use href="#i-hanger"/></svg></span>
<span class="c"><svg><use href="#i-hanger"/></svg></span>
</div>
<div class="cs-body">
<div class="cs-t">衣柜分享 · 8 件</div>
<div class="cs-tags">
<span class="pill">部分衣物</span>
<span class="cs-exp">7 天后过期</span>
</div>
</div>
</button>
<button class="cs-card seg-c0" data-nav="closet-share-detail" data-params='{"uuid":"s2"}'>
<div class="cs-thumb">
<span class="c"><svg><use href="#i-hanger"/></svg></span>
<span class="c"><svg><use href="#i-hanger"/></svg></span>
<span class="c"><svg><use href="#i-hanger"/></svg></span>
<span class="c"><svg><use href="#i-hanger"/></svg></span>
</div>
<div class="cs-body">
<div class="cs-t">衣柜分享 · 24 件</div>
<div class="cs-tags">
<span class="pill">全量衣橱</span>
<span class="cs-exp">长期有效</span>
</div>
</div>
</button>
<button class="cs-card seg-c1" data-nav="outfit-share-detail" data-params='{"uuid":"s3"}'>
<div class="cs-thumb is-photo"><svg><use href="#g-coat"/></svg></div>
<div class="cs-body">
<div class="cs-owner">
<span class="oav"><svg><use href="#i-user"/></svg></span>
<span class="onm">林小满</span>
</div>
<div class="cs-t">通勤极简三件套</div>
<div class="cs-tags">
<span class="pill">穿搭分享 · 3 件</span>
<span class="cs-exp">有效</span>
</div>
</div>
</button>
<button class="cs-card seg-c1 is-dead" data-nav="closet-share-detail" data-params='{"uuid":"s4"}'>
<div class="cs-thumb is-photo"><svg><use href="#g-dress"/></svg></div>
<div class="cs-body">
<div class="cs-owner">
<span class="oav"><svg><use href="#i-user"/></svg></span>
<span class="onm">周意</span>
</div>
<div class="cs-t">秋日法式复古</div>
<div class="cs-tags">
<span class="pill">穿搭分享 · 5 件</span>
<span class="pill pill--line">已失效</span>
</div>
</div>
</button>
</div>
<div class="foot-note">没有更多了</div>
</div>
</div>
</section>
<!-- ============ 我的 ============ -->
<section class="screen" data-screen="profile" data-tab="4" data-state="list" data-states="list">
<div class="nav" data-nav="large">
<div class="nav-inner"></div>
<div class="nav-title">我的</div>
</div>
<div class="scroll">
<div class="head">
<div class="eyebrow">Profile</div>
</div>
<div class="pf-hero">
<div class="pf-av"><svg><use href="#i-user"/></svg></div>
<div style="min-width:0">
<div class="pf-name">微信用户</div>
<div class="pf-sub">
<span class="pill">女</span>
<span class="pill pill--ink">月度会员</span>
<span class="pill pill--line">天秤座</span>
</div>
</div>
<button class="pf-edit" data-sheet="profile-edit">编辑资料<svg><use href="#i-chev-r"/></svg></button>
</div>
<div class="pf-warn">
<svg><use href="#i-info"/></svg>
<span>你的上传额度仅剩 2 次,点击购买额度包</span>
<svg style="width:12px;height:12px;margin-left:auto"><use href="#i-chev-r"/></svg>
</div>
<button class="pf-quota" data-nav="mall">
<div class="pf-quota-hd">
<span class="eyebrow">Quota</span>
<span class="qk">我的额度</span>
<svg><use href="#i-chev-r"/></svg>
</div>
<div class="stats">
<div class="stat"><div class="stat-n num">2<small>/10</small></div><div class="stat-l">上传</div></div>
<div class="stat"><div class="stat-n num">6<small>/10</small></div><div class="stat-l">AI 推荐</div></div>
<div class="stat"><div class="stat-n num">8<small>/10</small></div><div class="stat-l">社区分享</div></div>
<div class="stat"><div class="stat-n num">4<small>/10</small></div><div class="stat-l">衣柜分享</div></div>
</div>
</button>
<div class="grp-hd" style="margin-top:34px"><span class="gh-cn">账户</span><span class="gh-en">Account</span></div>
<div class="rows">
<button class="row" data-nav="order">
<svg class="row-ic"><use href="#i-doc"/></svg>
<span class="row-lb">我的订单</span>
<svg class="row-ch"><use href="#i-chev-r"/></svg>
</button>
<button class="row" data-nav="notification">
<svg class="row-ic"><use href="#i-bell"/></svg>
<span class="row-lb">通知</span>
<span class="row-badge">3</span>
<svg class="row-ch"><use href="#i-chev-r"/></svg>
</button>
<button class="row" data-nav="outfit">
<svg class="row-ic"><use href="#i-star"/></svg>
<span class="row-lb">我的收藏</span>
<svg class="row-ch"><use href="#i-chev-r"/></svg>
</button>
<button class="row" data-nav="mall" data-params='{"view":"flow"}'>
<svg class="row-ic"><use href="#i-gauge"/></svg>
<span class="row-lb">额度明细</span>
<svg class="row-ch"><use href="#i-chev-r"/></svg>
</button>
</div>
<div class="grp-hd" style="margin-top:34px"><span class="gh-cn">设置</span><span class="gh-en">Settings</span></div>
<div class="rows">
<button class="row" data-sheet="profile-edit">
<svg class="row-ic"><use href="#i-pencil"/></svg>
<span class="row-lb">编辑资料</span>
<svg class="row-ch"><use href="#i-chev-r"/></svg>
</button>
<button class="row" data-sheet="profile-edit">
<svg class="row-ic"><use href="#i-calendar"/></svg>
<span class="row-lb">设置生日</span>
<span class="row-vl">未设置</span>
<svg class="row-ch"><use href="#i-chev-r"/></svg>
</button>
<button class="row" data-toast="客服与反馈敬请期待">
<svg class="row-ic"><use href="#i-headphones"/></svg>
<span class="row-lb">客服与反馈</span>
<svg class="row-ch"><use href="#i-chev-r"/></svg>
</button>
<button class="row" data-toast="纸条AI衣橱 v1.0.0">
<svg class="row-ic"><use href="#i-info"/></svg>
<span class="row-lb">关于纸条AI衣橱</span>
<svg class="row-ch"><use href="#i-chev-r"/></svg>
</button>
</div>
<div class="pf-ver">v1.0.0</div>
</div>
</section>
<!-- ============ 上传衣物 ============ -->
<section class="screen" data-screen="upload" data-state="idle" data-states="idle,processing,failed">
<div class="nav" data-nav="large">
<div class="nav-inner">
<button class="nav-back" data-back><svg><use href="#i-chev-l"/></svg></button>
</div>
<div class="nav-title">上传衣物</div>
</div>
<div class="scroll">
<div class="st" data-when="idle">
<div class="head">
<div class="eyebrow">Upload</div>
<h1 class="display">上传衣物</h1>
</div>
<button class="up-drop" data-as="upload-source">
<svg class="up-drop-ic"><use href="#i-camera"/></svg>
<span class="up-drop-t">拍照或从相册选择</span>
<span class="up-drop-d">支持 JPG / PNG,单张不超过 20MB</span>
<span class="up-drop-d">上传消耗 1 次上传额度</span>
</button>
<div class="up-note">AI 将自动抠图并识别 15 项属性</div>
</div>
<div class="st" data-when="processing">
<div class="head">
<div class="eyebrow">Processing</div>
<h1 class="display">AI 正在识别你的衣物…</h1>
<div class="wd-stat">通常需要 10 秒左右,请稍候</div>
</div>
<div class="up-preview"><svg><use href="#g-shirt"/></svg></div>
<div class="up-steps">
<div class="up-step is-done"><span class="up-dot"></span><span class="up-lb">排队中</span></div>
<div class="up-step is-on"><span class="up-dot"></span><span class="up-lb">AI 抠图</span></div>
<div class="up-step"><span class="up-dot"></span><span class="up-lb">智能分类</span></div>
</div>
</div>
<div class="st" data-when="failed">
<div class="empty" style="padding-top:88px">
<div class="up-bang">!</div>
<div class="empty-t">识别失败:图片模糊</div>
<div class="empty-d">本次上传额度已自动退回</div>
</div>
<div class="up-duo">
<button class="btn btn--ghost" data-toast="请重新选择图片">重新上传</button>
<button class="btn btn--ink" data-nav="clothes-detail" data-params='{"uuid":"c9"}'>手动填写信息</button>
</div>
</div>
</div>
</section>
<!-- ============ 衣物详情 ============ -->
<section class="screen" data-screen="clothes-detail" data-state="list" data-edit="0" data-readonly="0" data-states="list,processing,failed,invalid">
<div class="nav" data-nav="large">
<div class="nav-inner">
<button class="nav-back" data-back><svg><use href="#i-chev-l"/></svg></button>
<span class="spacer"></span>
<button class="nav-action nav-action--ink only-editable cd-edit-btn" data-toggle-edit>编辑</button>
</div>
<div class="nav-title">衣物详情</div>
</div>
<div class="scroll">
<div class="st" data-when="invalid">
<div class="empty">
<svg class="empty-ic"><use href="#i-hanger"/></svg>
<div class="empty-t">衣物不存在</div>
<div class="empty-d">缺少衣物标识,无法查看详情</div>
<button class="btn btn--ink empty-b" data-nav="wardrobe">返回衣橱</button>
</div>
</div>
<div class="st" data-when="processing">
<div class="head">
<div class="eyebrow">Processing</div>
<h1 class="display">AI 正在识别你的衣物…</h1>
<div class="wd-stat">通常需要 10 秒左右,请稍候</div>
</div>
<div class="up-preview"><svg><use href="#g-dress"/></svg></div>
<div class="up-steps">
<div class="up-step is-done"><span class="up-dot"></span><span class="up-lb">排队中</span></div>
<div class="up-step is-done"><span class="up-dot"></span><span class="up-lb">AI 抠图</span></div>
<div class="up-step is-on"><span class="up-dot"></span><span class="up-lb">智能分类</span></div>
</div>
</div>
<div class="st" data-when="failed">
<div class="empty" style="padding-top:64px">
<div class="up-bang">!</div>
<div class="empty-t">识别失败:图片模糊</div>
<div class="empty-d">本次上传额度已自动退回,你可以删除或重新上传</div>
</div>
<div class="grp-hd" style="margin-top:38px"><span class="gh-cn">基础信息</span><span class="gh-en">Basics</span></div>
<div class="cd-specs">
<div class="spec"><span class="spec-k">名称</span><span class="spec-v">未命名衣物</span></div>
<div class="spec"><span class="spec-k">失败原因</span><span class="spec-v">图片模糊</span></div>
</div>
</div>
<div class="st" data-when="list">
<div class="cd-photo"><svg><use href="#g-shirt"/></svg></div>
<div class="cd-name">
<div class="eyebrow">Item</div>
<h1 class="display cd-view-w" style="margin-top:11px">白色棉质衬衫</h1>
<input class="cd-input cd-edit-w" value="白色棉质衬衫" placeholder="衣物名称">
</div>
<div class="grp-hd" style="margin-top:34px"><span class="gh-cn">基础属性</span><span class="gh-en">Basics</span></div>
<div class="cd-specs">
<button class="spec" data-attr="category_main"><span class="spec-k">大类</span><span class="spec-v">上装</span><svg class="spec-ch"><use href="#i-chev-r"/></svg></button>
<button class="spec" data-attr="category_sub"><span class="spec-k">小类</span><span class="spec-v">衬衫</span><svg class="spec-ch"><use href="#i-chev-r"/></svg></button>
<button class="spec" data-attr="style"><span class="spec-k">风格</span><span class="spec-v">简约</span><svg class="spec-ch"><use href="#i-chev-r"/></svg></button>
<button class="spec" data-attr="color_main"><span class="spec-k">主色</span><span class="spec-v"><span class="dot" style="background:#FFFFFF"></span>白色</span><svg class="spec-ch"><use href="#i-chev-r"/></svg></button>
<button class="spec" data-attr="color_sub"><span class="spec-k">副色</span><span class="spec-v"><span class="dot" style="background:#F5EFE0"></span>米色</span><svg class="spec-ch"><use href="#i-chev-r"/></svg></button>
</div>
<div class="grp-hd" style="margin-top:32px"><span class="gh-cn">版型与材质</span><span class="gh-en">Cut &amp; Fabric</span></div>
<div class="cd-specs">
<button class="spec" data-attr="thickness"><span class="spec-k">厚度</span><span class="spec-v">适中</span><svg class="spec-ch"><use href="#i-chev-r"/></svg></button>
<button class="spec" data-attr="version"><span class="spec-k">版型</span><span class="spec-v">常规合身</span><svg class="spec-ch"><use href="#i-chev-r"/></svg></button>
<button class="spec" data-attr="material"><span class="spec-k">材质</span><span class="spec-v">纯棉</span><svg class="spec-ch"><use href="#i-chev-r"/></svg></button>
<button class="spec" data-attr="pattern"><span class="spec-k">花纹</span><span class="spec-v">纯色</span><svg class="spec-ch"><use href="#i-chev-r"/></svg></button>
<button class="spec" data-attr="sleeve_type"><span class="spec-k">袖型</span><span class="spec-v">长袖</span><svg class="spec-ch"><use href="#i-chev-r"/></svg></button>
<button class="spec" data-attr="clothes_type"><span class="spec-k">衣长</span><span class="spec-v">常规</span><svg class="spec-ch"><use href="#i-chev-r"/></svg></button>
<button class="spec" data-attr="neckline_type"><span class="spec-k">领型</span><span class="spec-v">翻领</span><svg class="spec-ch"><use href="#i-chev-r"/></svg></button>
</div>
<div class="grp-hd" style="margin-top:32px"><span class="gh-cn">智能量化评估</span><span class="gh-en">AI Assessment</span></div>
<div class="cd-specs">
<button class="spec" data-attr="formality">
<span class="spec-k">正式程度</span>
<span class="spec-v"><span class="dots"><i class="on"></i><i class="on"></i><i class="on"></i><i></i><i></i></span></span>
<svg class="spec-ch"><use href="#i-chev-r"/></svg>
</button>
<button class="spec" data-attr="occasions">
<span class="spec-k">适用场合</span>
<span class="spec-v" style="display:flex;flex-wrap:wrap;gap:5px;justify-content:flex-end">
<span class="pill pill--line">通勤</span>
<span class="pill pill--line">约会</span>
<span class="pill pill--line">聚会</span>
</span>
<svg class="spec-ch"><use href="#i-chev-r"/></svg>
</button>
<button class="spec" data-attr="visual_impact">
<span class="spec-k">视觉冲击力</span>
<span class="spec-v"><span class="dots"><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i></i></span></span>
<svg class="spec-ch"><use href="#i-chev-r"/></svg>
</button>
</div>
<div class="grp-hd" style="margin-top:32px"><span class="gh-cn">备注</span><span class="gh-en">Notes</span></div>
<div class="cd-note cd-view-w">衣橱里最百搭的一件,配西裤和牛仔裤都不会出错。</div>
<textarea class="cd-note-area cd-edit-w" placeholder="添加备注…">衣橱里最百搭的一件,配西裤和牛仔裤都不会出错。</textarea>
</div>
</div>
<div class="dock only-editable">
<button class="btn btn--ink btn--block cd-edit-w" data-toast="已保存">保存</button>
<button class="cd-del cd-view-w" data-modal="delete-clothes">删除这件衣物</button>
</div>
</section>
<!-- ============ 穿搭详情 ============ -->
<section class="screen" data-screen="outfit-detail" data-state="list" data-owner="1" data-states="list">
<div class="nav" data-nav="large">
<div class="nav-inner">
<button class="nav-back" data-back><svg><use href="#i-chev-l"/></svg></button>
<span class="spacer"></span>
<button class="nav-more only-owner" data-as="outfit-more"><svg><use href="#i-ellipsis"/></svg></button>
</div>
<div class="nav-title">周末咖啡散步</div>
</div>
<div class="scroll">
<div class="od-photo">
<div class="collage" data-n="3">
<div class="cg"><svg><use href="#g-shirt"/></svg></div>
<div class="cg"><svg><use href="#g-pants"/></svg></div>
<div class="cg"><svg><use href="#g-bag"/></svg></div>
<span class="cg-badge">3 件</span>
</div>
</div>
<div class="od-info">
<h1 class="display">周末咖啡散步</h1>
<div class="od-tags">
<span class="pill pill--line">休闲</span>
<span class="pill">自建</span>
<span class="pill">仅自己可见</span>
</div>
<p class="od-desc">白衬衫配阔腿西裤,松弛又利落。包袋选深棕,压住整体的轻飘感,周末去咖啡馆或逛展都合适。</p>
</div>
<div class="grp-hd" style="margin-top:34px"><span class="gh-cn">包含衣物</span><span class="gh-en">Items</span></div>
<div class="od-items">
<button class="od-item" data-nav="clothes-detail" data-params='{"uuid":"c1"}'>
<span class="od-item-img"><svg><use href="#g-shirt"/></svg></span>
<span>白色棉质衬衫</span>
</button>
<button class="od-item" data-nav="clothes-detail" data-params='{"uuid":"c2"}'>
<span class="od-item-img"><svg><use href="#g-pants"/></svg></span>
<span>高腰阔腿西裤</span>
</button>
<button class="od-item" data-nav="clothes-detail" data-params='{"uuid":"c7"}'>
<span class="od-item-img"><svg><use href="#g-bag"/></svg></span>
<span>深棕通勤托特包</span>
</button>
</div>
</div>
<div class="dock">
<div class="dock-row">
<button class="dock-ic" data-like>
<svg class="ic-o"><use href="#i-heart"/></svg>
<svg class="ic-f" style="display:none"><use href="#i-heart-f"/></svg>
<span class="num">12</span>
</button>
<button class="dock-ic only-visitor" data-collect>
<svg class="ic-o"><use href="#i-star"/></svg>
<svg class="ic-f" style="display:none"><use href="#i-star-f"/></svg>
</button>
<span class="spacer"></span>
<button class="btn btn--ghost btn--sm only-owner" data-modal="public-outfit">公开到社区</button>
<button class="btn btn--ink btn--sm" data-sheet="share">分享</button>
</div>
</div>
</section>
<!-- ============ 创建 / 编辑穿搭 ============ -->
<section class="screen" data-screen="outfit-edit" data-view="form" data-views="form,select" data-mode="create" data-state="list" data-states="list,skeleton,empty">
<div class="nav" data-nav="large">
<div class="nav-inner">
<button class="nav-back" data-back><svg><use href="#i-chev-l"/></svg></button>
<span class="spacer"></span>
<button class="nav-action oe-nav-select" data-view-to="form">取消</button>
</div>
<div class="nav-title oe-nav-form">创建穿搭</div>
<div class="nav-title oe-nav-select">选择衣橱单品</div>
</div>
<div class="scroll">
<div class="vw" data-when="form">
<div class="head">
<div class="eyebrow">New Look</div>
<h1 class="display">创建穿搭</h1>
</div>
<div class="oe-preview">
<div class="oe-empty">
<svg><use href="#i-shirt"/></svg>
<div class="t">还没有选择衣物</div>
<div class="d">点击下方「选择衣物」添加你的单品</div>
</div>
</div>
<div class="oe-form">
<div class="oe-field">
<div class="oe-field-hd"><span class="k"><b>穿搭名称</b> *</span><span class="c num">0/32</span></div>
<input class="oe-input" placeholder="给这套穿搭起个名字" maxlength="32">
</div>
<div class="oe-field">
<div class="oe-field-hd"><span class="k">穿搭描述</span><span class="c num">0/500</span></div>
<textarea class="oe-area" placeholder="简单描述这套穿搭的灵感或亮点" maxlength="500"></textarea>
</div>
<div class="oe-field">
<div class="oe-field-hd"><span class="k">适合场景</span><span class="c num">0/100</span></div>
<input class="oe-input" placeholder="例如:通勤、约会、旅行" maxlength="100">
</div>
</div>
<button class="oe-pick" data-view-to="select" style="margin-top:32px">
<span class="pk">
<span class="t">选择衣橱单品</span>
<span class="d" style="display:block">选择 1~10 件衣物合成画报</span>
</span>
<span class="pv">未选择</span>
<svg><use href="#i-chev-r"/></svg>
</button>
</div>
<div class="vw" data-when="select">
<div class="segbar" style="margin-top:0">
<div class="seg">
<button class="seg-item is-on">全部</button>
<button class="seg-item">上装</button>
<button class="seg-item">下装</button>
<button class="seg-item">连衣裙</button>
<button class="seg-item">外套</button>
<button class="seg-item">鞋</button>
<button class="seg-item">配饰</button>
</div>
</div>
<div class="wd-grid">
<button class="wd-tile" data-pick>
<div class="tile-img"><svg><use href="#g-shirt"/></svg><span class="tile-check"><svg><use href="#i-check"/></svg></span></div>
<div class="tile-name">白色棉质衬衫</div>
<div class="tile-sub">上装 · 衬衫 · 白色</div>
</button>
<button class="wd-tile" data-pick>
<div class="tile-img"><svg><use href="#g-pants"/></svg><span class="tile-check"><svg><use href="#i-check"/></svg></span></div>
<div class="tile-name">高腰阔腿西裤</div>
<div class="tile-sub">下装 · 长裤 · 黑色</div>
</button>
<button class="wd-tile" data-pick>
<div class="tile-img"><svg><use href="#g-sweater"/></svg><span class="tile-check"><svg><use href="#i-check"/></svg></span></div>
<div class="tile-name">米色针织开衫</div>
<div class="tile-sub">上装 · 针织衫 · 米色</div>
</button>
<button class="wd-tile" data-pick>
<div class="tile-img"><svg><use href="#g-dress"/></svg><span class="tile-check"><svg><use href="#i-check"/></svg></span></div>
<div class="tile-name">黑色吊带连衣裙</div>
<div class="tile-sub">连衣裙 · 吊带裙 · 黑色</div>
</button>
<button class="wd-tile" data-pick>
<div class="tile-img"><svg><use href="#g-coat"/></svg><span class="tile-check"><svg><use href="#i-check"/></svg></span></div>
<div class="tile-name">驼色羊绒大衣</div>
<div class="tile-sub">外套 · 大衣 · 棕色</div>
</button>
<button class="wd-tile" data-pick>
<div class="tile-img"><svg><use href="#g-shoe"/></svg><span class="tile-check"><svg><use href="#i-check"/></svg></span></div>
<div class="tile-name">白色真皮小白鞋</div>
<div class="tile-sub">鞋 · 板鞋 · 白色</div>
</button>
</div>
</div>
</div>
<div class="oe-bar vw" data-when="form">
<div class="sb">
<button class="btn btn--text oe-only-edit" data-modal="delete-outfit">删除穿搭</button>
<span class="spacer"></span>
<button class="btn btn--ink is-off" style="min-width:132px" data-toast="请填写穿搭名称">保存</button>
</div>
</div>
<div class="oe-bar vw" data-when="select">
<div class="sb">
<div class="sb-l">
<div class="sb-n num">已选 0 件</div>
<div class="sb-d">最多可选择 10 件单品</div>
</div>
<button class="btn btn--ink" style="min-width:104px" data-view-to="form">确定</button>
</div>
</div>
</section>
<!-- ============ AI 穿搭推荐 ============ -->
<section class="screen" data-screen="ai-recommend" data-state="generating" data-states="generating,result,empty">
<div class="nav" data-nav="large">
<div class="nav-inner">
<button class="nav-back" data-back><svg><use href="#i-chev-l"/></svg></button>
</div>
<div class="nav-title">AI 穿搭推荐</div>
</div>
<div class="scroll">
<div class="st" data-when="generating">
<div class="ai-gen">
<div class="ai-ring"></div>
<div class="t">AI 正在为你搭配…</div>
<div class="d">结合今日运势与你的衣橱</div>
</div>
</div>
<div class="st" data-when="empty">
<div class="empty">
<svg class="empty-ic"><use href="#i-hanger"/></svg>
<div class="empty-t">还没有可用衣物</div>
<div class="empty-d">先上传几件处理成功的衣物吧</div>
<button class="btn btn--ink empty-b" data-nav="upload">去上传</button>
</div>
</div>
<div class="st" data-when="result">
<div class="od-photo">
<div class="collage" data-n="4">
<div class="cg"><svg><use href="#g-shirt"/></svg></div>
<div class="cg"><svg><use href="#g-pants"/></svg></div>
<div class="cg"><svg><use href="#g-coat"/></svg></div>
<div class="cg"><svg><use href="#g-bag"/></svg></div>
<span class="cg-badge">4 件</span>
</div>
</div>
<div class="od-info">
<h1 class="display">通勤极简三件套</h1>
<div class="od-tags">
<span class="pill pill--line">通勤</span>
<span class="pill pill--ink">AI 推荐</span>
</div>
<p class="od-desc">白衬衫打底,阔腿西裤收出腰线,外面加一件驼色大衣。整体只用三种颜色,适合 18~24℃ 的春秋通勤。</p>
</div>
<div class="grp-hd" style="margin-top:34px"><span class="gh-cn">推荐单品</span><span class="gh-en">Picks</span></div>
<div class="od-items">
<button class="od-item" data-nav="clothes-detail" data-params='{"uuid":"c1"}'>
<span class="od-item-img"><svg><use href="#g-shirt"/></svg></span>
<span>白色棉质衬衫</span>
</button>
<button class="od-item" data-nav="clothes-detail" data-params='{"uuid":"c2"}'>
<span class="od-item-img"><svg><use href="#g-pants"/></svg></span>
<span>高腰阔腿西裤</span>
</button>
<button class="od-item" data-nav="clothes-detail" data-params='{"uuid":"c5"}'>
<span class="od-item-img"><svg><use href="#g-coat"/></svg></span>
<span>驼色羊绒大衣</span>
</button>
<button class="od-item" data-nav="clothes-detail" data-params='{"uuid":"c7"}'>
<span class="od-item-img"><svg><use href="#g-bag"/></svg></span>
<span>深棕通勤托特包</span>
</button>
</div>
</div>
</div>
<div class="dock st" data-when="result">
<div class="dock-row">
<button class="btn btn--ghost" style="flex:1" data-sheet="scene">换一套</button>
<button class="btn btn--ink" style="flex:1.4" data-toast="已保存到我的穿搭">保存到我的穿搭</button>
</div>
<div class="ai-hint">换一套将再消耗 1 次推荐额度</div>
</div>
</section>
<!-- ============ 创建衣柜分享 ============ -->
<section class="screen" data-screen="closet-share-create" data-view="config" data-views="config,select,success" data-sharetype="1" data-state="list" data-states="list,skeleton,empty">
<div class="nav" data-nav="large">
<div class="nav-inner">
<button class="nav-back" data-back><svg><use href="#i-chev-l"/></svg></button>
<span class="spacer"></span>
<button class="nav-action csc-nav-select" data-view-to="config">取消</button>
</div>
<div class="nav-title csc-nav-config">创建分享</div>
<div class="nav-title csc-nav-select">选择衣物</div>
</div>
<div class="scroll">
<div class="vw" data-when="config">
<div class="head">
<div class="eyebrow">New Share</div>
<h1 class="display">创建分享</h1>
</div>
<div class="grp-hd" style="margin-top:34px"><span class="gh-cn">分享方式</span><span class="gh-en">Method</span></div>
<div class="csc-opts">
<button class="csc-opt is-on" data-sharetype-to="1">
<span class="ck"><svg><use href="#i-check"/></svg></span>
<span class="k"><span class="t">部分衣物</span><span class="d">挑选几件衣物分享给好友</span></span>
</button>
<button class="csc-opt" data-sharetype-to="2">
<span class="ck"><svg><use href="#i-check"/></svg></span>
<span class="k"><span class="t">全量快照</span><span class="d">分享当前衣橱的全部衣物</span></span>
</button>
</div>
<button class="oe-pick csc-only-partial" data-view-to="select" style="margin-top:14px">
<span class="pk"><span class="t">选择衣物</span></span>
<span class="pv">未选择</span>
<svg><use href="#i-chev-r"/></svg>
</button>
<div class="grp-hd" style="margin-top:34px"><span class="gh-cn">有效期</span><span class="gh-en">Expiry</span></div>
<div class="csc-exp">
<button class="csc-exp-item">1 天</button>
<button class="csc-exp-item is-on">7 天</button>
<button class="csc-exp-item">30 天</button>
<button class="csc-exp-item">长期有效</button>
</div>
</div>
<div class="vw" data-when="select">
<div class="segbar" style="margin-top:0">
<div class="seg">
<button class="seg-item is-on">全部</button>
<button class="seg-item">上装</button>
<button class="seg-item">下装</button>
<button class="seg-item">连衣裙</button>
<button class="seg-item">外套</button>
<button class="seg-item">鞋</button>
<button class="seg-item">配饰</button>
</div>
</div>
<div class="wd-grid">
<button class="wd-tile is-picked" data-pick>
<div class="tile-img"><svg><use href="#g-shirt"/></svg><span class="tile-check"><svg><use href="#i-check"/></svg></span></div>
<div class="tile-name">白色棉质衬衫</div>
<div class="tile-sub">上装 · 衬衫 · 白色</div>
</button>
<button class="wd-tile" data-pick>
<div class="tile-img"><svg><use href="#g-pants"/></svg><span class="tile-check"><svg><use href="#i-check"/></svg></span></div>
<div class="tile-name">高腰阔腿西裤</div>
<div class="tile-sub">下装 · 长裤 · 黑色</div>
</button>
<button class="wd-tile" data-pick>
<div class="tile-img"><svg><use href="#g-sweater"/></svg><span class="tile-check"><svg><use href="#i-check"/></svg></span></div>
<div class="tile-name">米色针织开衫</div>
<div class="tile-sub">上装 · 针织衫 · 米色</div>
</button>
<button class="wd-tile" data-pick>
<div class="tile-img"><svg><use href="#g-dress"/></svg><span class="tile-check"><svg><use href="#i-check"/></svg></span></div>
<div class="tile-name">黑色吊带连衣裙</div>
<div class="tile-sub">连衣裙 · 吊带裙 · 黑色</div>
</button>
<button class="wd-tile" data-pick>
<div class="tile-img"><svg><use href="#g-coat"/></svg><span class="tile-check"><svg><use href="#i-check"/></svg></span></div>
<div class="tile-name">驼色羊绒大衣</div>
<div class="tile-sub">外套 · 大衣 · 棕色</div>
</button>
<button class="wd-tile" data-pick>
<div class="tile-img"><svg><use href="#g-bag"/></svg><span class="tile-check"><svg><use href="#i-check"/></svg></span></div>
<div class="tile-name">深棕通勤托特包</div>
<div class="tile-sub">配饰 · 包袋 · 棕色</div>
</button>
</div>
</div>
<div class="vw" data-when="success">
<div class="empty" style="padding-top:72px">
<div class="csc-ok"><svg><use href="#i-check"/></svg></div>
<div class="empty-t">分享已创建</div>
</div>
<div class="csc-preview">
<div class="csc-preview-hd">
<span class="oav"><svg><use href="#i-user"/></svg></span>
<span class="tx">微信用户 向你分享了 8 件衣物</span>
</div>
<div class="csc-preview-body">
<span class="c"><svg><use href="#g-shirt"/></svg></span>
<span class="c"><svg><use href="#g-pants"/></svg></span>
<span class="c"><svg><use href="#g-dress"/></svg></span>
<span class="c"><svg><use href="#g-bag"/></svg></span>
</div>
</div>
</div>
</div>
<div class="dock vw" data-when="config">
<button class="btn btn--ink btn--block" data-view-to="success">确认分享(消耗 1 次衣柜分享额度)</button>
</div>
<div class="dock vw" data-when="select">
<div class="sb">
<div class="sb-l">
<div class="sb-n num">已选 1 件</div>
<div class="sb-d">部分衣物分享至少选择 1 件</div>
</div>
<button class="btn btn--ink" style="min-width:104px" data-view-to="config">确定</button>
</div>
</div>
<div class="dock vw" data-when="success">
<div class="dock-row">
<button class="btn btn--ghost" style="flex:1" data-nav="closet-share">完成</button>
<button class="btn btn--ink" style="flex:1.3" data-nav="closet-share-detail" data-params='{"uuid":"s1"}'>查看分享</button>
</div>
</div>
</section>
<!-- ============ 衣柜分享详情 ============ -->
<section class="screen" data-screen="closet-share-detail" data-state="list" data-owner="1" data-states="list,needlogin,invalid">
<div class="nav" data-nav="large">
<div class="nav-inner">
<button class="nav-back" data-back><svg><use href="#i-chev-l"/></svg></button>
</div>
<div class="nav-title">分享详情</div>
</div>
<div class="scroll">
<div class="st" data-when="needlogin">
<div class="empty">
<svg class="empty-ic"><use href="#i-user"/></svg>
<div class="empty-t">请先登录</div>
<div class="empty-d">登录后即可查看好友分享的衣柜</div>
<button class="btn btn--ink empty-b" data-nav="login">去登录</button>
</div>
</div>
<div class="st" data-when="invalid">
<div class="empty">
<svg class="empty-ic"><use href="#i-share"/></svg>
<div class="empty-t">分享已过期</div>
<div class="empty-d">该分享链接已超过有效期</div>
<button class="btn btn--ink empty-b" data-nav="wardrobe">返回首页</button>
</div>
</div>
<div class="st" data-when="list">
<div class="head">
<div class="eyebrow">Shared Closet</div>
<h1 class="display">林小满的衣橱</h1>
</div>
<div class="sd-owner">
<div class="sd-av"><svg><use href="#i-user"/></svg></div>
<div style="min-width:0">
<div class="sd-t">林小满 分享了 8 件衣物</div>
<div class="sd-d">有效期至 2026-09-22 18:30</div>
</div>
</div>
<div class="wd-grid">
<div class="wd-tile"><div class="tile-img"><svg><use href="#g-shirt"/></svg></div><div class="tile-name">白色棉质衬衫</div><div class="tile-sub">上装 · 衬衫</div></div>
<div class="wd-tile"><div class="tile-img"><svg><use href="#g-pants"/></svg></div><div class="tile-name">高腰阔腿西裤</div><div class="tile-sub">下装 · 长裤</div></div>
<div class="wd-tile"><div class="tile-img"><svg><use href="#g-sweater"/></svg></div><div class="tile-name">米色针织开衫</div><div class="tile-sub">上装 · 针织衫</div></div>
<div class="wd-tile"><div class="tile-img"><svg><use href="#g-dress"/></svg></div><div class="tile-name">黑色吊带连衣裙</div><div class="tile-sub">连衣裙 · 吊带裙</div></div>
<div class="wd-tile"><div class="tile-img"><svg><use href="#g-coat"/></svg></div><div class="tile-name">驼色羊绒大衣</div><div class="tile-sub">外套 · 大衣</div></div>
<div class="wd-tile"><div class="tile-img"><svg><use href="#g-shoe"/></svg></div><div class="tile-name">白色真皮小白鞋</div><div class="tile-sub">鞋 · 板鞋</div></div>
<div class="wd-tile"><div class="tile-img"><svg><use href="#g-bag"/></svg></div><div class="tile-name">深棕通勤托特包</div><div class="tile-sub">配饰 · 包袋</div></div>
<div class="wd-tile"><div class="tile-img is-empty"><svg><use href="#i-hanger"/></svg></div><div class="tile-name">未命名衣物</div><div class="tile-sub">&nbsp;</div></div>
</div>
<div class="foot-note">没有更多了</div>
</div>
</div>
<div class="dock st" data-when="list">
<button class="btn btn--ink btn--block" data-sheet="share">分享给好友</button>
<button class="cd-del only-owner" data-modal="cancel-share">取消分享</button>
</div>
</section>
<!-- ============ 穿搭分享详情 ============ -->
<section class="screen" data-screen="outfit-share-detail" data-state="list" data-owner="0" data-states="list,needlogin,invalid">
<div class="nav" data-nav="large">
<div class="nav-inner">
<button class="nav-back" data-back><svg><use href="#i-chev-l"/></svg></button>
</div>
<div class="nav-title">穿搭分享</div>
</div>
<div class="scroll">
<div class="st" data-when="needlogin">
<div class="empty">
<svg class="empty-ic"><use href="#i-user"/></svg>
<div class="empty-t">请先登录</div>
<div class="empty-d">登录后即可查看好友分享的穿搭</div>
<button class="btn btn--ink empty-b" data-nav="login">去登录</button>
</div>
</div>
<div class="st" data-when="invalid">
<div class="empty">
<svg class="empty-ic"><use href="#i-shirt"/></svg>
<div class="empty-t">分享已取消</div>
<div class="empty-d">该分享已被创建者取消</div>
<button class="btn btn--ink empty-b" data-nav="wardrobe">返回首页</button>
</div>
</div>
<div class="st" data-when="list">
<div class="sd-owner">
<div class="sd-av"><svg><use href="#i-user"/></svg></div>
<div style="min-width:0">
<div class="sd-t">林小满 分享了穿搭</div>
<div class="sd-d">共 3 件单品</div>
</div>
</div>
<div class="od-photo" style="margin-top:24px">
<div class="collage" data-n="3">
<div class="cg"><svg><use href="#g-shirt"/></svg></div>
<div class="cg"><svg><use href="#g-pants"/></svg></div>
<div class="cg"><svg><use href="#g-coat"/></svg></div>
<span class="cg-badge">3 件</span>
</div>
</div>
<div class="od-info">
<h1 class="display">通勤极简三件套</h1>
<div class="od-tags">
<span class="pill pill--line">通勤</span>
<span class="pill">自建</span>
</div>
<p class="od-desc">驼色大衣打底,白衬衫做层次,配西裤收出腰线。整体只用三种颜色,开会与通勤都撑得住。</p>
</div>
<div class="grp-hd" style="margin-top:34px"><span class="gh-cn">包含衣物</span><span class="gh-en">Items</span></div>
<div class="od-items">
<button class="od-item" data-nav="clothes-detail" data-params='{"uuid":"c1","readonly":"1"}'>
<span class="od-item-img"><svg><use href="#g-shirt"/></svg></span>
<span>白色棉质衬衫</span>
</button>
<button class="od-item" data-nav="clothes-detail" data-params='{"uuid":"c2","readonly":"1"}'>
<span class="od-item-img"><svg><use href="#g-pants"/></svg></span>
<span>高腰阔腿西裤</span>
</button>
<button class="od-item" data-nav="clothes-detail" data-params='{"uuid":"c5","readonly":"1"}'>
<span class="od-item-img"><svg><use href="#g-coat"/></svg></span>
<span>驼色羊绒大衣</span>
</button>
</div>
</div>
</div>
<div class="dock st" data-when="list">
<button class="btn btn--ink btn--block" data-sheet="share">分享给好友</button>
<button class="cd-del only-owner" data-modal="cancel-share">取消分享</button>
</div>
</section>
<!-- ============ 通知列表 ============ -->
<section class="screen" data-screen="notification" data-state="list" data-states="list,skeleton,empty">
<div class="nav" data-nav="large">
<div class="nav-inner">
<button class="nav-back" data-back><svg><use href="#i-chev-l"/></svg></button>
</div>
<div class="nav-title">通知</div>
</div>
<div class="scroll">
<div class="head">
<div class="eyebrow">Inbox</div>
<h1 class="display">通知</h1>
</div>
<div class="segbar" style="margin-top:18px">
<div class="seg">
<button class="seg-item is-on">全部</button>
<button class="seg-item">点赞</button>
<button class="seg-item">订单</button>
<button class="seg-item">系统</button>
</div>
</div>
<div class="st" data-when="skeleton">
<div style="padding:22px var(--pad) 0;display:flex;flex-direction:column;gap:26px">
<div style="display:flex;gap:13px"><div class="sk" style="width:34px;height:34px;border-radius:50%;flex-shrink:0"></div><div style="flex:1;display:flex;flex-direction:column;gap:9px"><div class="sk sk-ln" style="width:52%"></div><div class="sk sk-ln" style="width:88%"></div><div class="sk sk-ln" style="width:26%"></div></div></div>
<div style="display:flex;gap:13px"><div class="sk" style="width:34px;height:34px;border-radius:50%;flex-shrink:0"></div><div style="flex:1;display:flex;flex-direction:column;gap:9px"><div class="sk sk-ln" style="width:44%"></div><div class="sk sk-ln" style="width:76%"></div><div class="sk sk-ln" style="width:30%"></div></div></div>
<div style="display:flex;gap:13px"><div class="sk" style="width:34px;height:34px;border-radius:50%;flex-shrink:0"></div><div style="flex:1;display:flex;flex-direction:column;gap:9px"><div class="sk sk-ln" style="width:58%"></div><div class="sk sk-ln" style="width:70%"></div><div class="sk sk-ln" style="width:22%"></div></div></div>
</div>
</div>
<div class="st" data-when="empty">
<div class="empty">
<svg class="empty-ic"><use href="#i-bell"/></svg>
<div class="empty-t">还没有消息</div>
<div class="empty-d">穿搭被点赞、订单动态都会出现在这里</div>
</div>
</div>
<div class="st" data-when="list">
<div class="nt-list">
<button class="nt-item is-unread" data-nav="notification-detail" data-params='{"uuid":"n1"}'>
<span class="nt-ic"><svg><use href="#i-heart"/></svg></span>
<span class="nt-body">
<span class="nt-t">你的穿搭被点赞了</span>
<span class="nt-c">林小满 赞了你的穿搭「通勤极简三件套」,去看看吧</span>
<span class="nt-time">12 分钟前</span>
</span>
</button>
<button class="nt-item is-unread" data-nav="notification-detail" data-params='{"uuid":"n2"}'>
<span class="nt-ic"><svg><use href="#i-doc"/></svg></span>
<span class="nt-body">
<span class="nt-t">订单支付成功</span>
<span class="nt-c">你购买的「月度会员」已到账,有效期至 2026-10-15</span>
<span class="nt-time">今天</span>
</span>
</button>
<button class="nt-item is-unread" data-nav="notification-detail" data-params='{"uuid":"n3"}'>
<span class="nt-ic"><svg><use href="#i-bell"/></svg></span>
<span class="nt-body">
<span class="nt-t">AI 识别完成</span>
<span class="nt-c">「驼色羊绒大衣」已完成抠图与 15 项属性识别</span>
<span class="nt-time">今天</span>
</span>
</button>
<button class="nt-item" data-nav="notification-detail" data-params='{"uuid":"n4"}'>
<span class="nt-ic"><svg><use href="#i-heart"/></svg></span>
<span class="nt-body">
<span class="nt-t">你的穿搭被点赞了</span>
<span class="nt-c">陈屿 赞了你的穿搭「周末咖啡散步」</span>
<span class="nt-time">2026-09-13</span>
</span>
</button>
</div>
<div class="foot-note">没有更多了</div>
</div>
</div>
</section>
<!-- ============ 通知详情 ============ -->
<section class="screen" data-screen="notification-detail" data-state="list" data-states="list">
<div class="nav" data-nav="large">
<div class="nav-inner">
<button class="nav-back" data-back><svg><use href="#i-chev-l"/></svg></button>
</div>
<div class="nav-title">通知详情</div>
</div>
<div class="scroll">
<div class="nd-card">
<div class="nd-ic"><svg><use href="#i-heart"/></svg></div>
<div class="eyebrow">Like</div>
<h1 class="display" style="margin-top:12px">你的穿搭被点赞了</h1>
<div class="nd-time">2026-09-15 09:29</div>
<div class="nd-body">林小满 赞了你的穿搭「通勤极简三件套」,去看看吧。公开到社区的穿搭每被点赞一次,都会在这里留下记录。</div>
</div>
</div>
</section>
<!-- ============ 额度与会员 ============ -->
<section class="screen" data-screen="mall" data-view="mall" data-views="mall,flow" data-state="list" data-states="list,skeleton">
<div class="nav" data-nav="large">
<div class="nav-inner">
<button class="nav-back" data-back><svg><use href="#i-chev-l"/></svg></button>
</div>
<div class="nav-title">额度与会员</div>
</div>
<div class="scroll">
<div class="vw" data-when="mall">
<div class="head">
<div class="eyebrow">Membership</div>
<h1 class="display">额度与会员</h1>
</div>
<div class="ml-vip">
<div class="ml-vip-top">
<svg><use href="#i-crown"/></svg>
<div>
<div class="ml-vip-t">开通会员</div>
<div class="ml-vip-d">开通会员,解锁更多 AI 与上传权益</div>
</div>
</div>
<button class="ml-vip-btn" data-modal="order-confirm">立即开通</button>
</div>
<div class="ml-quota">
<div class="grp-hd"><span class="gh-cn">我的额度</span><span class="gh-en">Quota</span></div>
<div class="stats">
<div class="stat"><div class="stat-n num">2<small>/10</small></div><div class="stat-l">上传</div></div>
<div class="stat"><div class="stat-n num">6<small>/10</small></div><div class="stat-l">AI 推荐</div></div>
<div class="stat"><div class="stat-n num">8<small>/10</small></div><div class="stat-l">社区分享</div></div>
<div class="stat"><div class="stat-n num">4<small>/10</small></div><div class="stat-l">衣柜分享</div></div>
</div>
</div>
<button class="ml-entry" data-view-to="flow" style="margin-top:26px">
<span class="t">额度明细</span>
<svg><use href="#i-chev-r"/></svg>
</button>
<div class="segbar" style="margin-top:26px">
<div class="seg">
<button class="seg-item is-on">全部</button>
<button class="seg-item">会员包</button>
<button class="seg-item">上传包</button>
<button class="seg-item">AI 推荐包</button>
<button class="seg-item">衣柜分享包</button>
<button class="seg-item">搭配分享包</button>
</div>
</div>
<div class="ml-goods">
<div class="ml-good">
<span class="ml-good-ic"><svg><use href="#i-crown"/></svg></span>
<div class="ml-good-b">
<div class="ml-good-n">月度会员</div>
<div class="ml-good-d">30 天会员权益,含上传 20 次与 AI 推荐 30 次/天</div>
<div class="ml-price"><span class="now num">¥18.00</span><span class="old num">¥28.00</span></div>
</div>
<button class="btn btn--ink btn--sm" data-modal="order-confirm">购买</button>
</div>
<div class="ml-good">
<span class="ml-good-ic"><svg><use href="#i-camera"/></svg></span>
<div class="ml-good-b">
<div class="ml-good-n">上传额度包 · 20 次</div>
<div class="ml-good-d">永久有效,每次上传衣物消耗 1 次</div>
<div class="ml-price"><span class="now num">¥12.00</span></div>
</div>
<button class="btn btn--ink btn--sm" data-modal="order-confirm">购买</button>
</div>
<div class="ml-good">
<span class="ml-good-ic"><svg><use href="#i-sparkles"/></svg></span>
<div class="ml-good-b">
<div class="ml-good-n">AI 推荐额度包 · 30 次</div>
<div class="ml-good-d">每日 0 点重置,当日有效</div>
<div class="ml-price"><span class="now num">¥9.90</span><span class="old num">¥15.00</span></div>
</div>
<button class="btn btn--ink btn--sm" data-modal="order-confirm">购买</button>
</div>
<div class="ml-good">
<span class="ml-good-ic"><svg><use href="#i-hanger"/></svg></span>
<div class="ml-good-b">
<div class="ml-good-n">衣柜分享额度包 · 10 次</div>
<div class="ml-good-d">永久有效,创建衣柜分享时消耗 1 次</div>
<div class="ml-price"><span class="now num">¥6.00</span></div>
</div>
<button class="btn btn--ink btn--sm" data-modal="order-confirm">购买</button>
</div>
</div>
</div>
<div class="vw" data-when="flow">
<button class="ml-back" data-view-to="mall">← 返回商城</button>
<div class="head" style="padding-top:6px">
<div class="eyebrow">Quota Ledger</div>
<h1 class="display">额度明细</h1>
</div>
<div class="ml-flow">
<div class="fl-row">
<div class="fl-l"><div class="fl-r">上传衣物消耗</div><div class="fl-t">2026-09-14 10:22</div></div>
<div class="fl-v"><div class="fl-n is-down num">-1</div><div class="fl-s num">剩余 2</div></div>
</div>
<div class="fl-row">
<div class="fl-l"><div class="fl-r">购买上传额度包</div><div class="fl-t">2026-09-12 21:05</div></div>
<div class="fl-v"><div class="fl-n num">+20</div><div class="fl-s num">剩余 3</div></div>
</div>
<div class="fl-row">
<div class="fl-l"><div class="fl-r">AI 推荐消耗</div><div class="fl-t">2026-09-12 08:40</div></div>
<div class="fl-v"><div class="fl-n is-down num">-1</div><div class="fl-s num">剩余 6</div></div>
</div>
<div class="fl-row">
<div class="fl-l"><div class="fl-r">删除衣物回退</div><div class="fl-t">2026-09-10 19:12</div></div>
<div class="fl-v"><div class="fl-n num">+1</div><div class="fl-s num">剩余 7</div></div>
</div>
<div class="fl-row">
<div class="fl-l"><div class="fl-r">创建衣柜分享消耗</div><div class="fl-t">2026-09-08 15:31</div></div>
<div class="fl-v"><div class="fl-n is-down num">-1</div><div class="fl-s num">剩余 4</div></div>
</div>
</div>
<div class="foot-note">没有更多了</div>
</div>
</div>
</section>
<!-- ============ 我的订单 ============ -->
<section class="screen" data-screen="order" data-state="list" data-states="list,skeleton,empty">
<div class="nav" data-nav="large">
<div class="nav-inner">
<button class="nav-back" data-back><svg><use href="#i-chev-l"/></svg></button>
</div>
<div class="nav-title">我的订单</div>
</div>
<div class="scroll">
<div class="head">
<div class="eyebrow">Orders</div>
<h1 class="display">我的订单</h1>
</div>
<div class="segbar" style="margin-top:18px">
<div class="seg">
<button class="seg-item is-on">全部</button>
<button class="seg-item">待支付</button>
<button class="seg-item">已支付</button>
<button class="seg-item">已取消</button>
<button class="seg-item">已过期</button>
<button class="seg-item">已退款</button>
</div>
</div>
<div class="st" data-when="skeleton">
<div style="padding:22px var(--pad) 0;display:flex;flex-direction:column;gap:28px">
<div style="display:flex;flex-direction:column;gap:11px"><div class="sk sk-ln" style="width:40%"></div><div class="sk sk-ln" style="width:64%"></div><div class="sk sk-ln" style="width:32%"></div></div>
<div style="display:flex;flex-direction:column;gap:11px"><div class="sk sk-ln" style="width:46%"></div><div class="sk sk-ln" style="width:58%"></div><div class="sk sk-ln" style="width:28%"></div></div>
</div>
</div>
<div class="st" data-when="empty">
<div class="empty">
<svg class="empty-ic"><use href="#i-doc"/></svg>
<div class="empty-t">还没有订单</div>
<button class="btn btn--ink empty-b" data-nav="mall">去看看额度包</button>
</div>
</div>
<div class="st" data-when="list">
<div class="or-list">
<div class="or-card">
<div class="or-top">
<span class="or-no">订单 …A3F7</span>
<span class="pill">虚拟支付</span>
<span class="spacer"></span>
<span class="pill pill--ink">待支付</span>
</div>
<div class="or-name">月度会员</div>
<div class="or-benefit">30 天会员</div>
<div class="or-bot">
<span class="or-amt">实付<b>¥18.00</b></span>
<span class="or-cd">剩余 14:52</span>
<span class="spacer"></span>
<button class="btn btn--ink btn--sm" data-toast="请返回商城重新下单支付">去支付</button>
</div>
</div>
<div class="or-card">
<div class="or-top">
<span class="or-no">订单 …F5B2</span>
<span class="spacer"></span>
<span class="pill pill--ink">待支付</span>
</div>
<div class="or-name">搭配分享额度包 · 5 次</div>
<div class="or-bot">
<span class="or-amt">实付<b>¥4.90</b></span>
<span class="or-cd">剩余 08:31</span>
<span class="spacer"></span>
<button class="btn btn--ghost btn--sm" data-modal="cancel-order">取消订单</button>
<button class="btn btn--ink btn--sm" data-toast="请返回商城重新下单支付">去支付</button>
</div>
</div>
<div class="or-card">
<div class="or-top">
<span class="or-no">订单 …B91C</span>
<span class="pill">虚拟支付</span>
<span class="spacer"></span>
<span class="pill pill--ring">已支付</span>
</div>
<div class="or-name">上传额度包 · 20 次</div>
<div class="or-bot">
<span class="or-amt">实付<b>¥12.00</b></span>
<span class="spacer"></span>
<button class="btn btn--ghost btn--sm" data-modal="refund-order">申请退款</button>
</div>
</div>
<div class="or-card">
<div class="or-top">
<span class="or-no">订单 …C4D8</span>
<span class="pill">虚拟支付</span>
<span class="spacer"></span>
<span class="pill pill--faint">已退款</span>
</div>
<div class="or-name">AI 推荐额度包 · 30 次</div>
<div class="or-bot">
<span class="or-amt">实付<b>¥9.90</b></span>
</div>
</div>
<div class="or-card" style="opacity:.5">
<div class="or-top">
<span class="or-no">订单 …7E20</span>
<span class="pill">虚拟支付</span>
<span class="spacer"></span>
<span class="pill pill--mute">已过期</span>
</div>
<div class="or-name">衣柜分享额度包 · 10 次</div>
<div class="or-bot">
<span class="or-amt">实付<b>¥6.00</b></span>
</div>
</div>
</div>
<div class="foot-note">没有更多了</div>
</div>
</div>
</section>
<!-- ============ 设计规范 ============ -->
<section class="screen" data-screen="spec" data-state="list" data-states="list">
<div class="nav" data-nav="large">
<div class="nav-inner">
<button class="nav-back" data-back><svg><use href="#i-chev-l"/></svg></button>
</div>
<div class="nav-title">设计规范</div>
</div>
<div class="scroll">
<div class="head">
<div class="eyebrow">Design System</div>
<h1 class="display">设计规范</h1>
</div>
<div class="sp-sec">
<div class="grp-hd" style="padding:0 0 14px"><span class="gh-cn">零彩色灰阶</span><span class="gh-en">Ink</span></div>
<div class="sp-swatches">
<div class="sp-sw"><i style="background:#0A0A0A"></i><div class="n">墨黑</div><div class="h">#0A0A0A</div></div>
<div class="sp-sw"><i style="background:#6E6E73"></i><div class="n">次要</div><div class="h">#6E6E73</div></div>
<div class="sp-sw"><i style="background:#AEAEB2"></i><div class="n">弱化</div><div class="h">#AEAEB2</div></div>
<div class="sp-sw"><i style="background:#C9C9CE"></i><div class="n">占位</div><div class="h">#C9C9CE</div></div>
<div class="sp-sw"><i style="background:#F7F7F5"></i><div class="n">纸面 2</div><div class="h">#F7F7F5</div></div>
<div class="sp-sw"><i style="background:#FFFFFF"></i><div class="n">纸面</div><div class="h">#FFFFFF</div></div>
<div class="sp-sw"><i style="background:#1C1C1E"></i><div class="n">深色块</div><div class="h">#1C1C1E</div></div>
</div>
<div style="margin-top:16px;font-size:11.5px;line-height:1.75;color:var(--ink-3)">
全稿仅允许以上灰阶。唯一彩色例外是业务数据:幸运色色点、衣物主色色点、色板选择器。
</div>
</div>
<div class="sp-sec">
<div class="grp-hd" style="padding:0 0 16px"><span class="gh-cn">双字阶</span><span class="gh-en">Type Scale</span></div>
<div class="sp-rows">
<div class="sp-row"><span class="meta">Display 34</span><span class="demo"><span class="display">我的衣橱</span></span></div>
<div class="sp-row"><span class="meta">Title 26</span><span class="demo"><span class="t-xl">通勤极简三件套</span></span></div>
<div class="sp-row"><span class="meta">Head 20</span><span class="demo"><span class="t-lg">天秤座 · 8.0</span></span></div>
<div class="sp-row"><span class="meta">Body 17</span><span class="demo"><span class="t-md">白色棉质衬衫</span></span></div>
<div class="sp-row"><span class="meta">Text 15</span><span class="demo"><span class="t-bd">把你的衣橱,交给 AI 打理</span></span></div>
<div class="sp-row"><span class="meta">Caption 13</span><span class="demo"><span class="t-sm">通常需要 10 秒左右,请稍候</span></span></div>
<div class="sp-row"><span class="meta">Eyebrow 10</span><span class="demo"><span class="eyebrow">Wardrobe · AI Stylist</span></span></div>
</div>
<div style="margin-top:18px;font-size:11.5px;line-height:1.75;color:var(--ink-3)">
衬线(Songti SC / Georgia)用于页面主标题、数字大数与穿搭名;无衬线(PingFang SC)用于正文、按钮与标签。10px 大写英文 eyebrow 是全稿最关键的「高级感装置」。
</div>
</div>
<div class="sp-sec">
<div class="grp-hd" style="padding:0 0 16px"><span class="gh-cn">按钮与胶囊</span><span class="gh-en">Controls</span></div>
<div class="sp-btns">
<button class="btn btn--ink btn--sm">实心黑</button>
<button class="btn btn--ghost btn--sm">描边</button>
<button class="btn btn--plain btn--sm">浅填充</button>
<button class="btn btn--ink btn--sm is-off">禁用</button>
<button class="btn btn--text">文字下划线</button>
</div>
<div class="sp-btns">
<span class="pill pill--ink">AI 推荐</span>
<span class="pill pill--ring">已支付</span>
<span class="pill pill--mute">已过期</span>
<span class="pill pill--faint">已退款</span>
<span class="pill">中性</span>
<span class="pill pill--line">休闲</span>
</div>
<div style="margin-top:16px;font-size:11.5px;line-height:1.75;color:var(--ink-3)">
旧版蓝/绿/橙/红状态色语义已重建为:实心黑=进行中/强调,描边黑=已完成,浅灰=失效/已读,极淡描边=历史记录。删除与取消一律用黑色下划线文字按钮,不依赖红色。
</div>
</div>
<div class="sp-sec">
<div class="grp-hd" style="padding:0 0 16px"><span class="gh-cn">毛玻璃浮层</span><span class="gh-en">Glass</span></div>
<div class="sp-glass">
导航栏、底部标签、分段条、弹窗与抽屉统一使用 rgba(255,255,255,.72) + saturate(180%) blur(20px) + 0.5px 发丝边。每屏玻璃层不超过两层,避免滚动掉帧。
</div>
</div>
<div class="sp-sec">
<div class="grp-hd" style="padding:0 0 16px"><span class="gh-cn">度量与发丝线</span><span class="gh-en">Metrics</span></div>
<div class="sp-meter">
<div class="r"><b>页面边距</b><span>20px</span></div>
<div class="r"><b>区块间距</b><span>32px</span></div>
<div class="r"><b>块内间距</b><span>16px</span></div>
<div class="r"><b>发丝线</b><span>0.5px rgba(0,0,0,.08)</span></div>
<div class="r"><b>图片圆角</b><span>4px(大块内容保持直角)</span></div>
<div class="r"><b>控件圆角</b><span>10px / 胶囊 999px</span></div>
<div class="r"><b>缓动</b><span>cubic-bezier(.32,.72,0,1) · 320~420ms</span></div>
</div>
</div>
<div class="sp-sec" style="padding-bottom:40px">
<div class="grp-hd" style="padding:0 0 16px"><span class="gh-cn">衣物线稿占位</span><span class="gh-en">Line Art</span></div>
<div class="wd-grid" style="padding:0">
<div class="wd-tile"><div class="tile-img"><svg><use href="#g-shirt"/></svg></div><div class="tile-name">上装</div></div>
<div class="wd-tile"><div class="tile-img"><svg><use href="#g-pants"/></svg></div><div class="tile-name">下装</div></div>
<div class="wd-tile"><div class="tile-img"><svg><use href="#g-dress"/></svg></div><div class="tile-name">连衣裙</div></div>
<div class="wd-tile"><div class="tile-img"><svg><use href="#g-coat"/></svg></div><div class="tile-name">外套</div></div>
<div class="wd-tile"><div class="tile-img"><svg><use href="#g-shoe"/></svg></div><div class="tile-name">鞋</div></div>
<div class="wd-tile"><div class="tile-img"><svg><use href="#g-bag"/></svg></div><div class="tile-name">配饰</div></div>
</div>
<div style="margin-top:18px;font-size:11.5px;line-height:1.75;color:var(--ink-3)">
原型中后端 processed_image 不可得,统一用内联 SVG 灰度线稿占位:1:1 画幅、居中留白、无边框、4px 圆角,像买手店目录里的商品线稿。
</div>
</div>
</div>
</section>
<!-- ==SCREENS== -->
</main>
<nav class="tabbar" id="tabbar" hidden>
<button class="tab-item" data-tab="0"><svg><use href="#i-hanger"/></svg><span class="tab-tx">衣橱</span></button>
<button class="tab-item" data-tab="1"><svg><use href="#i-shirt"/></svg><span class="tab-tx">穿搭</span></button>
<button class="tab-item" data-tab="2"><svg><use href="#i-sparkles"/></svg><span class="tab-tx">运势</span></button>
<button class="tab-item" data-tab="3"><svg><use href="#i-share"/></svg><span class="tab-tx">分享</span></button>
<button class="tab-item" data-tab="4"><svg><use href="#i-user"/></svg><span class="tab-tx">我的</span><span class="tab-badge">3</span></button>
</nav>
<div class="overlayRoot" id="overlayRoot">
<div class="layer" id="layer-modal"></div>
<div class="layer" id="layer-sheet"></div>
<div class="layer" id="layer-as"></div>
<div class="layer toast-layer" id="layer-toast"></div>
</div>
</div>
<div class="wb-hint">点击页内元素可真实跳转 · 左侧切换页面 · 右侧切换状态与视图</div>
</div>
<aside class="wb-state">
<div class="wb-state-hd">状态 / 视图</div>
<div class="wb-state-bd" id="statePanel"></div>
</aside>
</div>
<script>
(function () {
'use strict';
var $ = function (s, r) { return (r || document).querySelector(s); };
var $$ = function (s, r) { return Array.prototype.slice.call((r || document).querySelectorAll(s)); };
var ic = function (n, cls) { return '<svg' + (cls ? ' class="' + cls + '"' : '') + '><use href="#' + n + '"/></svg>'; };
/* ============================================================
§A 页面注册表 · 左侧索引
============================================================ */
var PAGES = [
{ grp: '登录', items: [ { id: 'login', nm: '微信授权登录', tag: '' } ] },
{ grp: '核心 Tab', items: [
{ id: 'wardrobe', nm: '我的衣橱', tag: 'T1' },
{ id: 'outfit', nm: '穿搭', tag: 'T2' },
{ id: 'horoscope', nm: '每日运势', tag: 'T3' },
{ id: 'closet-share', nm: '分享', tag: 'T4' },
{ id: 'profile', nm: '我的', tag: 'T5' }
] },
{ grp: '详情', items: [
{ id: 'clothes-detail', nm: '衣物详情', tag: '4 态' },
{ id: 'outfit-detail', nm: '穿搭详情', tag: '双角色' },
{ id: 'notification', nm: '通知列表', tag: '3 态' },
{ id: 'notification-detail', nm: '通知详情', tag: '' }
] },
{ grp: '表单流程', items: [
{ id: 'upload', nm: '上传衣物', tag: '3 态' },
{ id: 'outfit-edit', nm: '创建 / 编辑穿搭', tag: '2 视图' },
{ id: 'ai-recommend', nm: 'AI 穿搭推荐', tag: '3 态' }
] },
{ grp: '分享', items: [
{ id: 'closet-share-create', nm: '创建衣柜分享', tag: '3 视图' },
{ id: 'closet-share-detail', nm: '衣柜分享详情', tag: '3 态' },
{ id: 'outfit-share-detail', nm: '穿搭分享详情', tag: '3 态' }
] },
{ grp: '交易', items: [
{ id: 'mall', nm: '额度与会员', tag: '2 视图' },
{ id: 'order', nm: '我的订单', tag: '3 态' }
] },
{ grp: '规范', items: [ { id: 'spec', nm: '设计规范', tag: '' } ] }
];
var TAB_OF = { wardrobe: 0, outfit: 1, horoscope: 2, 'closet-share': 3, profile: 4 };
var TAB_NAME = ['wardrobe', 'outfit', 'horoscope', 'closet-share', 'profile'];
/* 每屏默认参数:每次进入都回到干净状态 */
var DEFAULTS = {
'outfit-detail': { owner: '1' },
'clothes-detail': { readonly: '0', edit: '0', state: 'list' },
'closet-share-detail': { owner: '1', state: 'list' },
'outfit-share-detail': { owner: '0', state: 'list' },
'outfit-edit': { view: 'form', mode: 'create', state: 'list' },
'closet-share-create': { view: 'config', sharetype: '1', state: 'list' },
'mall': { view: 'mall', state: 'list' },
'upload': { state: 'idle' },
'ai-recommend': { state: 'result' },
'notification': { state: 'list' },
'order': { state: 'list' },
'wardrobe': { state: 'list' },
'outfit': { state: 'list', seg: '0' },
'horoscope': { state: 'list' },
'closet-share': { state: 'list', seg: '0' }
};
/* 分段切换时的空态文案(逐字对齐 .wxml) */
var OF_EMPTY = {
0: { t: '还没有穿搭', d: '从衣橱挑几件,搭一套吧', b: '创建穿搭' },
1: { t: '还没有收藏的穿搭', d: '在社区或 AI 推荐中点亮小星星,喜欢的穿搭会出现在这里', b: '' },
2: { t: '还没有公开的穿搭', d: '把喜欢的穿搭公开到社区,让大家看到你的搭配', b: '' }
};
var CS_EMPTY = {
0: { t: '还没有分享', d: '把衣橱或精选衣物分享给好友', b: '新建分享' },
1: { t: '还没有收到分享', d: '好友分享给你的衣橱或穿搭会出现在这里', b: '' }
};
/* ============================================================
§B 路由 · 栈式导航
============================================================ */
var App = {
stack: [ { name: 'wardrobe', params: {} } ],
get top() { return this.stack[this.stack.length - 1]; },
go: function (name, params) {
params = params || {};
var scr = $('.screen[data-screen="' + name + '"]');
if (!scr) return;
if (name in TAB_OF) {
this.stack = [ { name: name, params: params } ];
setTab(TAB_OF[name]);
} else {
var t = this.top;
if (t.name === name) { t.params = params; }
else { this.stack.push({ name: name, params: params }); }
}
this.render();
},
back: function () {
var scr = $('.screen[data-screen="' + this.top.name + '"]');
/* 子视图优先回退到主视图 */
if (scr && scr.dataset.view) {
var views = (scr.dataset.views || '').split(',');
if (views.length && scr.dataset.view !== views[0]) {
setView(scr, views[0]);
return;
}
}
if (this.stack.length > 1) { this.stack.pop(); this.render(); }
},
render: function () {
var top = this.top;
var name = top.name;
$$('.screen').forEach(function (s) {
s.classList.toggle('is-active', s.dataset.screen === name);
});
var scr = $('.screen[data-screen="' + name + '"]');
applyParams(scr, top.params);
resetScroll(scr);
bindScroll(scr);
var tabbar = $('#tabbar');
var isTab = name in TAB_OF;
tabbar.hidden = !isTab;
if (isTab) setTab(TAB_OF[name]);
if (top.params.openSheet) {
var key = top.params.openSheet;
window.setTimeout(function () { openSheetByName(key); }, 400);
}
markIndex(name);
buildStatePanel(scr, name);
}
};
function applyParams(scr, params) {
if (!scr) return;
var d = DEFAULTS[scr.dataset.screen] || {};
var merged = {};
var k;
for (k in d) { merged[k] = d[k]; }
for (k in params) { if (k !== 'openSheet') merged[k] = params[k]; }
['owner', 'readonly', 'edit', 'state', 'view', 'seg', 'mode', 'sharetype'].forEach(function (key) {
if (key in merged) scr.dataset[key] = merged[key];
});
if (scr.dataset.screen === 'outfit') syncOutfitSeg(scr);
if (scr.dataset.screen === 'closet-share') syncShareSeg(scr);
if (scr.dataset.screen === 'clothes-detail') syncEditBtn(scr);
if (scr.dataset.screen === 'outfit-edit') { refreshPicks(scr); refreshSave(scr); }
if (scr.dataset.screen === 'closet-share-create') { refreshPicks(scr); syncShareType(scr); }
}
function resetScroll(scr) {
if (!scr) return;
$$('.scroll', scr).forEach(function (el) { el.scrollTop = 0; });
}
function bindScroll(scr) {
var sc = $('.scroll', scr);
var nav = $('.nav', scr);
if (!sc || !nav) return;
if (sc.__navBound) { nav.classList.toggle('is-glass', sc.scrollTop > 34); return; }
sc.__navBound = true;
var fn = function () { nav.classList.toggle('is-glass', sc.scrollTop > 34); };
sc.addEventListener('scroll', fn, { passive: true });
fn();
}
function setTab(i) {
$$('#tabbar .tab-item').forEach(function (b, idx) {
b.classList.toggle('is-on', idx === i);
});
}
/* ============================================================
§C 状态 / 视图切换
============================================================ */
function setView(scr, v) {
if (!scr || !v) return;
scr.dataset.view = v;
if (scr.dataset.screen === 'outfit-edit') { refreshPicks(scr); refreshPreview(scr); refreshSave(scr); }
if (scr.dataset.screen === 'closet-share-create') { refreshPicks(scr); syncShareType(scr); }
if (scr.dataset.screen === 'mall' && v === 'flow') { /* 额度明细 */ }
buildStatePanel(scr, scr.dataset.screen);
}
function syncEditBtn(scr) {
var b = $('.cd-edit-btn', scr);
if (b) b.textContent = scr.dataset.edit === '1' ? '取消' : '编辑';
}
/* ============================================================
§D 弹层控制器
============================================================ */
var LAYER = {
modal: $('#layer-modal'),
sheet: $('#layer-sheet'),
as: $('#layer-as'),
toast: $('#layer-toast')
};
var activeModal = null;
var activeSheet = null;
function closeAll() {
LAYER.modal.classList.remove('is-open'); LAYER.modal.innerHTML = '';
LAYER.sheet.classList.remove('is-open'); LAYER.sheet.innerHTML = '';
LAYER.as.classList.remove('is-open'); LAYER.as.innerHTML = '';
activeModal = null;
activeSheet = null;
}
function openModalByName(name) {
var cfg = MODALS[name];
if (!cfg) return;
activeModal = cfg;
LAYER.modal.innerHTML =
'<div class="scrim" data-close></div>' +
'<div class="modal-wrap"><div class="modal">' +
'<div class="modal-body">' +
(cfg.icon ? '<div class="lg-gift-ic">' + ic(cfg.icon) + '</div>' : '') +
'<div class="modal-title">' + (cfg.title || '') + '</div>' +
(cfg.text ? '<div class="modal-text">' + cfg.text + '</div>' : '') +
(cfg.list ? '<div class="lg-gift-list">' + cfg.list + '</div>' : '') +
(cfg.editable ? '<input class="modal-input" placeholder="' + (cfg.placeholder || '') + '">' : '') +
'</div>' +
'<div class="modal-acts">' +
(cfg.single ? '' : '<button class="modal-act" data-close>' + (cfg.cancel || '取消') + '</button>') +
'<button class="modal-act modal-act--main" data-confirm>' + (cfg.confirm || '确定') + '</button>' +
'</div>' +
'</div></div>';
LAYER.modal.classList.add('is-open');
}
function openSheetByName(name) {
var cfg = SHEETS[name];
if (!cfg) return;
activeSheet = cfg;
LAYER.sheet.innerHTML =
'<div class="scrim" data-close></div>' +
'<div class="sheet-wrap"><div class="sheet">' +
'<div class="sheet-grab"></div>' +
'<div class="sheet-hd">' +
'<span class="sheet-t">' + (cfg.title || '') + '</span>' +
'<button class="sheet-x" ' + (cfg.onAction ? 'data-sheet-done' : 'data-close') + '>' + (cfg.action || '关闭') + '</button>' +
'</div>' +
'<div class="sheet-body">' + (cfg.html || '') + '</div>' +
(cfg.footer ? '<div class="sheet-foot">' + cfg.footer + '</div>' : '') +
'</div></div>';
LAYER.sheet.classList.add('is-open');
}
function openASByName(name) {
var cfg = AS[name];
if (!cfg) return;
LAYER.as.innerHTML =
'<div class="scrim" data-close></div>' +
'<div class="as-wrap">' +
'<div class="as-card">' +
(cfg.title ? '<div class="as-hd">' + cfg.title + '</div>' : '') +
cfg.items.map(function (it, i) { return '<button class="as-item" data-as-pick="' + i + '">' + it + '</button>'; }).join('') +
'</div>' +
'<button class="as-cancel" data-close>取消</button>' +
'</div>';
LAYER.as.classList.add('is-open');
LAYER.as.__cfg = cfg;
}
var toastTimer = null;
function toast(text) {
var L = LAYER.toast;
L.innerHTML = '<div class="toast-wrap"><div class="toast">' + text + '</div></div>';
L.classList.add('is-open');
window.clearTimeout(toastTimer);
toastTimer = window.setTimeout(function () {
var t = $('.toast', L);
if (t) t.classList.add('is-out');
window.setTimeout(function () { L.classList.remove('is-open'); L.innerHTML = ''; }, 280);
}, 1700);
}
/* ============================================================
§E 弹窗 / 抽屉 / 动作表 定义(文案逐字对齐 .wxml / .ts)
============================================================ */
var MODALS = {
gift: {
icon: 'i-sparkles',
title: '欢迎加入纸条AI衣橱',
text: '新人礼包已到账,请查收',
list:
'<div class="lg-gift-row">' + ic('i-crown') + '<span class="gn">体验会员</span><span class="gv">有效期至 2026-09-22</span></div>' +
'<div class="lg-gift-row">' + ic('i-camera') + '<span class="gn">上传额度</span><span class="gv">10 次 · 永久</span></div>' +
'<div class="lg-gift-row">' + ic('i-sparkles') + '<span class="gn">AI 推荐额度</span><span class="gv">10 次/天</span></div>' +
'<div class="lg-gift-row">' + ic('i-shirt') + '<span class="gn">搭配分享额度</span><span class="gv">10 次/天</span></div>' +
'<div class="lg-gift-row">' + ic('i-hanger') + '<span class="gn">衣柜分享额度</span><span class="gv">10 次/天</span></div>',
confirm: '开心收下',
onConfirm: function () { App.go('wardrobe'); }
},
birth: {
title: '完善个人信息',
text: '设置生日后即可查看今日星座运势',
confirm: '去完善',
cancel: '稍后再说',
onConfirm: function () { App.go('profile'); }
},
'delete-clothes': {
title: '删除这件衣物',
text: '删除后将退回 1 次上传额度,确认删除?',
confirm: '确认删除',
cancel: '取消',
onConfirm: function () { toast('已删除'); App.go('wardrobe'); }
},
'public-outfit': {
title: '公开到社区',
text: '公开后将展示在社区供他人点赞收藏,并消耗 1 次社区分享额度',
confirm: '确认公开',
cancel: '取消',
onConfirm: function () {
toast('已公开');
var s = $('.screen[data-screen="outfit-detail"]');
var t = $('.od-tags .pill:nth-child(3)', s);
if (t) t.textContent = '已公开';
var b = $('[data-modal="public-outfit"]', s);
if (b) b.textContent = '取消公开';
}
},
'delete-outfit': {
title: '确认删除这套穿搭?',
text: '删除后不可恢复,但不会影响衣橱内的单品。',
confirm: '确认删除',
cancel: '取消',
onConfirm: function () { toast('已删除'); App.go('outfit'); }
},
'cancel-share': {
title: '取消分享',
text: '取消后该分享链接将失效,且不返还衣柜分享额度',
confirm: '取消分享',
cancel: '取消',
onConfirm: function () { toast('已取消'); App.back(); }
},
'cancel-order': {
title: '取消订单',
text: '确认取消该订单?',
confirm: '确定',
cancel: '取消',
onConfirm: function () { toast('已取消'); }
},
'refund-order': {
title: '申请退款',
editable: true,
placeholder: '请填写退款原因',
confirm: '提交',
cancel: '取消',
onConfirm: function () {
var v = $('.modal-input', LAYER.modal);
if (!v || !v.value.trim()) { toast('请填写退款原因'); return 'keep'; }
toast('退款申请已提交,等待审核');
}
},
'order-confirm': {
title: '月度会员',
text: '30 天会员权益,含上传 20 次与 AI 推荐 30 次/天<br><span style="font-family:var(--serif);font-size:22px;color:var(--ink);display:inline-block;margin-top:12px">实付 ¥18.00</span>',
confirm: '立即支付',
cancel: '取消',
onConfirm: function () { toast('支付成功'); }
},
'quota-upload': {
title: '上传额度不足',
text: '当前剩余 0 次,购买额度包后可继续上传',
confirm: '去购买',
cancel: '取消',
onConfirm: function () { App.go('mall'); }
},
'quota-ai': {
title: 'AI 推荐额度不足',
text: '购买额度包后可继续生成 AI 穿搭推荐',
confirm: '去购买',
cancel: '取消',
onConfirm: function () { App.go('mall'); }
},
'ai-confirm': {
title: 'AI 穿搭推荐',
text: '本次将消耗 1 次 AI 推荐额度,生成后可保存到我的穿搭',
confirm: '开始生成',
cancel: '取消',
onConfirm: function () {
var s = $('.screen[data-screen="ai-recommend"]');
s.dataset.state = 'generating';
buildStatePanel(s, 'ai-recommend');
window.setTimeout(function () {
s.dataset.state = 'result';
buildStatePanel(s, 'ai-recommend');
toast('已为你生成一套穿搭');
}, 1800);
}
},
'upload-done': {
title: '衣物已上传',
text: 'AI 正在识别中,可在衣橱查看进度',
confirm: '继续上传',
cancel: '回到衣橱',
onConfirm: function () {
var s = $('.screen[data-screen="upload"]');
s.dataset.state = 'idle';
buildStatePanel(s, 'upload');
}
}
};
var SHEETS = {
'profile-edit': {
title: '编辑资料',
action: '完成',
html:
'<div style="padding:2px var(--pad) 0">' +
'<div style="display:flex;flex-direction:column;align-items:center;padding:8px 0 22px">' +
'<div class="pf-av" style="width:76px;height:76px">' + ic('i-user') + '</div>' +
'<div class="t-sm" style="margin-top:11px">点击更换头像</div>' +
'</div>' +
'</div>' +
'<div class="oe-field"><div class="oe-field-hd"><span class="k">昵称</span><span class="c num">0/32</span></div>' +
'<input class="oe-input" placeholder="请输入昵称" maxlength="32"></div>' +
'<button class="oe-field" style="display:block;width:100%;text-align:left" data-as="gender">' +
'<div class="oe-field-hd" style="margin-bottom:0"><span class="k">性别</span><span class="c" style="font-size:13.5px">请选择</span></div></button>' +
'<button class="oe-field" style="display:block;width:100%;text-align:left" data-toast="请选择生日">' +
'<div class="oe-field-hd" style="margin-bottom:0"><span class="k">生日</span><span class="c" style="font-size:13.5px">请选择生日</span></div></button>',
onAction: function () { toast('已保存'); }
},
share: {
title: '分享给好友',
action: '关闭',
html:
'<div class="csc-preview" style="margin:0 var(--pad)">' +
'<div class="csc-preview-hd"><span class="oav">' + ic('i-user') + '</span>' +
'<span class="tx">林小满 向你分享了穿搭「通勤极简三件套」</span></div>' +
'<div class="csc-preview-body">' +
'<span class="c">' + ic('g-shirt') + '</span><span class="c">' + ic('g-pants') + '</span>' +
'<span class="c">' + ic('g-coat') + '</span><span class="c">' + ic('g-bag') + '</span>' +
'</div>' +
'</div>' +
'<div class="t-sm" style="padding:16px var(--pad) 0;line-height:1.75">好友打开链接即可查看,无需登录你的账号。</div>',
footer: '<button class="btn btn--ink btn--block" data-toast="已唤起微信分享面板">分享给好友</button>'
},
scene: {
title: '选择推荐场景',
action: '关闭',
html:
'<div class="scene-cards">' +
'<button class="scene-card is-on" data-scene-to="1">' +
'<span class="sc-k"><span class="t">每日推荐</span><span class="d">按今日运势与衣橱自动搭配</span></span>' +
ic('i-check', 'sc-ck') +
'</button>' +
'<button class="scene-card" data-scene-to="2">' +
'<span class="sc-k"><span class="t">自定义场景</span><span class="d">描述你想去的场合</span></span>' +
ic('i-check', 'sc-ck') +
'</button>' +
'</div>' +
'<input class="scene-input" id="sceneInput" style="display:none" placeholder="例如:海边度假、周一例会、初次约会">',
footer:
'<button class="btn btn--ink btn--block" data-modal="ai-confirm">开始生成(消耗 1 次推荐额度)</button>' +
'<button class="btn btn--text btn--block" style="margin-top:16px" data-close>跳过,使用每日推荐</button>'
}
};
var AS = {
'upload-source': { items: ['拍照', '从相册选择'], onPick: function (i) {
closeAll();
if (i === 0 || i === 1) {
var s = $('.screen[data-screen="upload"]');
s.dataset.state = 'processing';
buildStatePanel(s, 'upload');
window.setTimeout(function () {
s.dataset.state = 'failed';
buildStatePanel(s, 'upload');
}, 2600);
}
} },
'outfit-more': { items: ['编辑穿搭', '删除穿搭'], onPick: function (i) {
closeAll();
if (i === 0) App.go('outfit-edit', { mode: 'edit' });
else openModalByName('delete-outfit');
} },
'gender': { items: ['男', '女'], onPick: function (i) {
closeAll();
var rows = $$('.oe-field .c', LAYER.sheet);
toast(i === 0 ? '已选择 男' : '已选择 女');
} }
};
/* ============================================================
§F 属性选择面板(对齐 clothes-detail ATTR_OPTIONS / COLOR_PRESETS)
============================================================ */
var ATTRS = {
category_main: { label: '大类', type: 'chips', opts: ['上装', '下装', '连衣裙', '外套', '鞋', '配饰'] },
category_sub: { label: '小类', type: 'text', opts: ['衬衫', 'T恤', '针织衫', '卫衣', '吊带', '西装', '长裤', '半身裙', '大衣', '板鞋', '包袋'] },
style: { label: '风格', type: 'chips', opts: ['简约', '休闲', '通勤', '运动', '甜美', '复古'] },
color_main: { label: '主色', type: 'color' },
color_sub: { label: '副色', type: 'color' },
thickness: { label: '厚度', type: 'chips', opts: ['薄', '适中', '厚'] },
version: { label: '版型', type: 'chips', opts: ['宽松', '修身', '阔腿', '紧身', '常规合身'] },
material: { label: '材质', type: 'chips', opts: ['纯棉', '牛仔布', '针织', '皮质', '羊毛', '涤纶'] },
pattern: { label: '花纹', type: 'chips', opts: ['纯色', '条纹', '格纹', '印花', '波点'] },
sleeve_type: { label: '袖型', type: 'chips', opts: ['无袖', '短袖', '长袖'] },
clothes_type: { label: '衣长', type: 'chips', opts: ['短款', '常规', '中长', '长款'] },
neckline_type: { label: '领型', type: 'chips', opts: ['圆领', 'V领', '方领', '翻领', '高领'] },
formality: { label: '正式程度', type: 'score' },
occasions: { label: '适用场合', type: 'multi', opts: ['休闲', '通勤', '约会', '运动', '聚会', '正式', '度假'] },
visual_impact: { label: '视觉冲击力', type: 'score' }
};
var COLORS = [
['白色', '#FFFFFF'], ['黑色', '#1C1C1E'], ['灰色', '#8E8E93'], ['红色', '#FF3B30'],
['粉色', '#FF2D55'], ['橙色', '#FF9500'], ['黄色', '#FFCC00'], ['绿色', '#34C759'],
['蓝色', '#007AFF'], ['紫色', '#5856D6'], ['棕色', '#A2845E'], ['米色', '#F5EFE0']
];
function openAttr(key) {
var a = ATTRS[key];
if (!a) return;
var body = '';
if (a.type === 'chips' || a.type === 'multi') {
body += '<div class="at-grid">' + a.opts.map(function (o) {
return '<button class="at-chip" data-chip="' + o + '">' + o + '</button>';
}).join('') + '</div>';
} else if (a.type === 'text') {
body += '<div class="at-grid">' + a.opts.map(function (o) {
return '<button class="at-chip" data-chip="' + o + '">' + o + '</button>';
}).join('') + '</div>';
body += '<div class="at-field" style="margin-top:14px"><input class="at-input" placeholder="请输入' + a.label + '"></div>';
} else if (a.type === 'color') {
body += '<div class="at-swatches">' + COLORS.map(function (c) {
return '<button class="at-sw" data-chip="' + c[0] + '" data-color="' + c[1] + '"><i style="background:' + c[1] + '"></i><span>' + c[0] + '</span></button>';
}).join('') + '</div>';
body += '<div class="at-field" style="margin-top:14px"><input class="at-input" placeholder="也可输入色值,如 #FFFFFF"></div>';
} else if (a.type === 'score') {
body += '<div class="at-score">' + [1, 2, 3, 4, 5].map(function (n) {
return '<button data-score="' + n + '">' + n + '</button>';
}).join('') + '</div>';
}
SHEETS.__attr = { title: a.label, action: '完成', html: body, onAction: function () { toast('已保存'); } };
openSheetByName('__attr');
}
/* ============================================================
§G 分段 / 多选 / 预览 同步
============================================================ */
function syncOutfitSeg(scr) {
var seg = scr.dataset.seg || '0';
var e = OF_EMPTY[seg] || OF_EMPTY[0];
var t = $('.of-empty-t', scr), d = $('.of-empty-d', scr), b = $('.of-empty-b', scr);
if (t) t.textContent = e.t;
if (d) d.textContent = e.d;
if (b) { b.style.display = e.b ? '' : 'none'; }
$$('.seg-item', scr).forEach(function (el) {
el.classList.toggle('is-on', el.dataset.segTo === seg);
});
}
function syncShareSeg(scr) {
var seg = scr.dataset.seg || '0';
var e = CS_EMPTY[seg] || CS_EMPTY[0];
var t = $('.of-empty-t', scr), d = $('.of-empty-d', scr), b = $('.of-empty-b', scr);
if (t) t.textContent = e.t;
if (d) d.textContent = e.d;
if (b) { b.style.display = e.b ? '' : 'none'; }
$$('.seg-item', scr).forEach(function (el) {
el.classList.toggle('is-on', el.dataset.segTo === seg);
});
}
function syncShareType(scr) {
var v = scr.dataset.sharetype || '1';
$$('.csc-opt', scr).forEach(function (el) {
el.classList.toggle('is-on', el.dataset.sharetypeTo === v);
});
}
function refreshPicks(scr) {
var n = $$('.wd-tile.is-picked', scr).length;
$$('.sb-n', scr).forEach(function (el) { el.textContent = '已选 ' + n + ' 件'; });
var pv = $('.oe-pick .pv', scr);
if (pv) {
pv.textContent = n ? '已选 ' + n + ' 件' : '未选择';
pv.classList.toggle('is-on', n > 0);
}
}
function refreshPreview(scr) {
var box = $('.oe-preview', scr);
if (!box) return;
var picked = $$('.wd-tile.is-picked', scr);
if (!picked.length) {
box.innerHTML = '<div class="oe-empty">' + ic('i-shirt') +
'<div class="t">还没有选择衣物</div>' +
'<div class="d">点击下方「选择衣物」添加你的单品</div></div>';
return;
}
var show = picked.slice(0, 4);
var cells = show.map(function (el, i) {
var u = el.querySelector('.tile-img svg use');
var href = u ? u.getAttribute('href') : '#i-hanger';
var more = (i === show.length - 1 && picked.length > 4) ? '<span class="cg-more">+' + (picked.length - 4) + '</span>' : '';
return '<div class="cg">' + ic(href.replace('#', '')) + more + '</div>';
}).join('');
box.innerHTML = '<div class="collage" data-n="' + Math.min(show.length, 4) + '">' + cells +
'<span class="cg-badge">' + picked.length + ' 件</span></div>';
}
function refreshSave(scr) {
var btn = $('.oe-bar[data-when="form"] .btn--ink', scr);
if (!btn) return;
var n = $$('.wd-tile.is-picked', scr).length;
var input = $('.oe-field .oe-input', scr);
var name = input ? input.value.trim() : '';
var ok = n > 0 && name;
btn.classList.toggle('is-off', !ok);
btn.dataset.toast = ok ? '已保存' : '请填写穿搭名称';
}
/* ============================================================
§H 左侧索引 / 右侧状态面板
============================================================ */
function buildIndex() {
var host = $('#wbIndex');
var html = '';
var n = 0;
PAGES.forEach(function (g) {
html += '<div class="wb-grp"><div class="wb-grp-hd">' + g.grp + '</div>';
g.items.forEach(function (it) {
n++;
html += '<button class="wb-item" data-idx="' + it.id + '">' +
'<span class="wb-idx num">' + (n < 10 ? '0' + n : n) + '</span>' +
'<span class="wb-nm">' + it.nm + '</span>' +
(it.tag ? '<span class="wb-tag">' + it.tag + '</span>' : '') +
'</button>';
});
html += '</div>';
});
host.innerHTML = html;
$$('.wb-item', host).forEach(function (b) {
b.addEventListener('click', function () { App.go(b.dataset.idx); });
});
}
function markIndex(name) {
$$('.wb-item').forEach(function (b) { b.classList.toggle('is-on', b.dataset.idx === name); });
var cur = $('.wb-item.is-on');
if (cur && cur.scrollIntoView) cur.scrollIntoView({ block: 'nearest' });
}
var STATE_LABEL = {
list: '正常列表', empty: '空态', skeleton: '骨架屏', error: '加载失败',
idle: '初始态', processing: '处理中', failed: '失败态', invalid: '失效 / 不存在',
needlogin: '需登录', generating: '生成中', result: '推荐结果', success: '成功态', submitting: '提交中'
};
var VIEW_LABEL = { form: '表单', select: '选择衣物', config: '配置', success: '成功预览', mall: '商城', flow: '额度明细' };
var SEG_LABEL = {};
function buildStatePanel(scr, name) {
var host = $('#statePanel');
if (!scr) { host.innerHTML = ''; return; }
var h = '';
var states = (scr.dataset.states || '').split(',').filter(Boolean);
if (states.length) {
h += '<div class="wb-sec">状态</div>';
states.forEach(function (s) {
h += '<button class="wb-chip ' + (scr.dataset.state === s ? 'is-on' : '') + '" data-set-state="' + s + '">' + (STATE_LABEL[s] || s) + '</button>';
});
}
var views = (scr.dataset.views || '').split(',').filter(Boolean);
if (views.length) {
h += '<div class="wb-sec">视图</div>';
views.forEach(function (v) {
h += '<button class="wb-chip ' + (scr.dataset.view === v ? 'is-on' : '') + '" data-set-view="' + v + '">' + (VIEW_LABEL[v] || v) + '</button>';
});
}
if (scr.dataset.seg !== undefined && $$('.seg-item[data-seg-to]', scr).length) {
h += '<div class="wb-sec">分段</div>';
$$('.seg-item[data-seg-to]', scr).forEach(function (el) {
var on = scr.dataset.seg === el.dataset.segTo;
h += '<button class="wb-chip ' + (on ? 'is-on' : '') + '" data-set-seg="' + el.dataset.segTo + '">' + el.textContent + '</button>';
});
}
if (scr.querySelector('.only-owner, .only-visitor')) {
h += '<div class="wb-sec">角色</div>';
h += '<button class="wb-chip ' + (scr.dataset.owner === '1' ? 'is-on' : '') + '" data-set-owner="1">属主视角</button>';
h += '<button class="wb-chip ' + (scr.dataset.owner === '0' ? 'is-on' : '') + '" data-set-owner="0">访客视角</button>';
}
if (scr.querySelector('.only-editable, .only-readonly')) {
h += '<div class="wb-sec">权限</div>';
h += '<button class="wb-chip ' + (scr.dataset.readonly === '0' ? 'is-on' : '') + '" data-set-readonly="0">可编辑</button>';
h += '<button class="wb-chip ' + (scr.dataset.readonly === '1' ? 'is-on' : '') + '" data-set-readonly="1">只读(分享)</button>';
}
if (scr.dataset.edit !== undefined && name === 'clothes-detail') {
h += '<div class="wb-sec">编辑态</div>';
h += '<button class="wb-chip ' + (scr.dataset.edit === '0' ? 'is-on' : '') + '" data-set-edit="0">浏览</button>';
h += '<button class="wb-chip ' + (scr.dataset.edit === '1' ? 'is-on' : '') + '" data-set-edit="1">编辑</button>';
}
if (!h) h = '<div class="wb-note">该屏为单状态页面,可直接点击页内元素体验交互。</div>';
h += '<div class="wb-note">当前屏:<code>' + name + '</code><br>点击页内任意可交互元素,会像真机一样跳转 / 弹层 / 反馈。</div>';
host.innerHTML = h;
}
/* ============================================================
§I 事件委托
============================================================ */
function currentScreen() {
return $('.screen.is-active');
}
document.addEventListener('click', function (e) {
var t = e.target;
if (!t || !t.closest) return;
/* 关闭弹层 */
if (t.closest('[data-close]')) { closeAll(); return; }
/* 弹窗确认 */
var cf = t.closest('[data-confirm]');
if (cf) {
var m = activeModal;
var keep = m && m.onConfirm ? m.onConfirm() : null;
if (keep === 'keep') return;
closeAll();
return;
}
/* 抽屉右上动作 */
if (t.closest('[data-sheet-done]')) {
var sh = activeSheet;
closeAll();
if (sh && sh.onAction) sh.onAction();
return;
}
/* ActionSheet 选择 */
var ap = t.closest('[data-as-pick]');
if (ap) {
var cfg = LAYER.as.__cfg;
var i = parseInt(ap.dataset.asPick, 10);
if (cfg && cfg.onPick) cfg.onPick(i);
else closeAll();
return;
}
/* 侧栏状态 / 视图 / 角色 / 权限 / 编辑态 */
var ss = t.closest('[data-set-state]');
if (ss) { var s1 = currentScreen(); s1.dataset.state = ss.dataset.setState; buildStatePanel(s1, s1.dataset.screen); return; }
var sv = t.closest('[data-set-view]');
if (sv) { setView(currentScreen(), sv.dataset.setView); return; }
var sg = t.closest('[data-set-seg]');
if (sg) { var s2 = currentScreen(); s2.dataset.seg = sg.dataset.setSeg; setSeg(s2, sg.dataset.setSeg); return; }
var so = t.closest('[data-set-owner]');
if (so) { var s3 = currentScreen(); s3.dataset.owner = so.dataset.setOwner; buildStatePanel(s3, s3.dataset.screen); return; }
var sr = t.closest('[data-set-readonly]');
if (sr) { var s4 = currentScreen(); s4.dataset.readonly = sr.dataset.setReadonly; buildStatePanel(s4, s4.dataset.screen); return; }
var se = t.closest('[data-set-edit]');
if (se) { var s5 = currentScreen(); s5.dataset.edit = se.dataset.setEdit; syncEditBtn(s5); buildStatePanel(s5, s5.dataset.screen); return; }
/* 底部标签 */
var tb = t.closest('#tabbar .tab-item');
if (tb) { App.go(TAB_NAME[parseInt(tb.dataset.tab, 10)]); return; }
/* 返回 */
if (t.closest('[data-back]')) { App.back(); return; }
/* 页内导航 */
var nv = t.closest('[data-nav]');
if (nv) {
var p = {};
if (nv.dataset.params) { try { p = JSON.parse(nv.dataset.params); } catch (err) { p = {}; } }
if (nv.dataset.open) p.openSheet = nv.dataset.open;
App.go(nv.dataset.nav, p);
return;
}
/* 视图切换 */
var vw = t.closest('[data-view-to]');
if (vw) { setView(vw.closest('.screen'), vw.dataset.viewTo); return; }
/* 分段 */
var sg2 = t.closest('[data-seg-to]');
if (sg2) { var s6 = sg2.closest('.screen'); setSeg(s6, sg2.dataset.segTo); return; }
/* 分享方式 / 有效期 */
var st = t.closest('[data-sharetype-to]');
if (st) { var s7 = st.closest('.screen'); s7.dataset.sharetype = st.dataset.sharetypeTo; syncShareType(s7); return; }
var ex = t.closest('.csc-exp-item');
if (ex) { $$('.csc-exp-item', ex.closest('.screen')).forEach(function (x) { x.classList.remove('is-on'); }); ex.classList.add('is-on'); return; }
var gs = t.closest('.segbar .seg-item');
if (gs) { $$('.seg-item', gs.parentNode).forEach(function (x) { x.classList.remove('is-on'); }); gs.classList.add('is-on'); return; }
/* 场景卡 */
var sc = t.closest('[data-scene-to]');
if (sc) {
$$('.scene-card', LAYER.sheet).forEach(function (x) { x.classList.remove('is-on'); });
sc.classList.add('is-on');
var inp = $('#sceneInput');
if (inp) inp.style.display = sc.dataset.sceneTo === '2' ? '' : 'none';
return;
}
/* 属性 chip / 评分 / 色板 */
var chip = t.closest('[data-chip]');
if (chip) {
var key = chip.dataset.chip;
if (chip.dataset.color) {
$$('.at-sw', LAYER.sheet).forEach(function (x) { x.classList.remove('is-on'); });
chip.classList.add('is-on');
var f = $('.at-field .at-input', LAYER.sheet);
if (f) f.value = chip.dataset.color;
} else if (chip.hasAttribute('data-single')) {
$$('.at-chip', LAYER.sheet).forEach(function (x) { x.classList.remove('is-on'); });
chip.classList.add('is-on');
} else {
chip.classList.toggle('is-on');
}
return;
}
var score = t.closest('[data-score]');
if (score) {
var n2 = parseInt(score.dataset.score, 10);
$$('[data-score]', LAYER.sheet).forEach(function (x) {
x.classList.toggle('is-on', parseInt(x.dataset.score, 10) <= n2);
});
return;
}
/* 属性行 → 打开对应面板 */
var at = t.closest('[data-attr]');
if (at) {
var scr = at.closest('.screen');
if (scr.dataset.edit !== '1') { toast('点击右上角「编辑」即可修改属性'); return; }
openAttr(at.dataset.attr);
return;
}
/* 编辑 / 取消 */
var eb = t.closest('[data-toggle-edit]');
if (eb) {
var s8 = eb.closest('.screen');
var on = s8.dataset.edit === '1';
s8.dataset.edit = on ? '0' : '1';
syncEditBtn(s8);
buildStatePanel(s8, s8.dataset.screen);
return;
}
/* 多选 */
var pk = t.closest('[data-pick]');
if (pk) {
var scr2 = pk.closest('.screen');
var cnt = $$('.wd-tile.is-picked', scr2).length;
if (!pk.classList.contains('is-picked') && cnt >= 10) { toast('最多选择 10 件衣物'); return; }
pk.classList.toggle('is-picked');
refreshPicks(scr2); refreshPreview(scr2); refreshSave(scr2);
return;
}
/* 点赞 / 收藏 */
var lk = t.closest('[data-like]');
if (lk) {
lk.classList.toggle('is-on');
var on2 = lk.classList.contains('is-on');
var o = $('.ic-o', lk), f2 = $('.ic-f', lk), num = $('.num', lk);
if (o) o.style.display = on2 ? 'none' : 'block';
if (f2) f2.style.display = on2 ? 'block' : 'none';
if (num) num.textContent = String(parseInt(num.textContent, 10) + (on2 ? 1 : -1));
return;
}
var cl = t.closest('[data-collect]');
if (cl) {
cl.classList.toggle('is-on');
var on3 = cl.classList.contains('is-on');
var o3 = $('.ic-o', cl), f3 = $('.ic-f', cl);
if (o3) o3.style.display = on3 ? 'none' : 'block';
if (f3) f3.style.display = on3 ? 'block' : 'none';
return;
}
/* 弹层触发 */
var md = t.closest('[data-modal]');
if (md) { closeAll(); openModalByName(md.dataset.modal); return; }
var sh2 = t.closest('[data-sheet]');
if (sh2) { closeAll(); openSheetByName(sh2.dataset.sheet); return; }
var as2 = t.closest('[data-as]');
if (as2) { closeAll(); openASByName(as2.dataset.as); return; }
var tt = t.closest('[data-toast]');
if (tt) { closeAll(); toast(tt.dataset.toast); return; }
});
function setSeg(scr, v) {
if (!scr) return;
scr.dataset.seg = v;
if (scr.dataset.screen === 'outfit') syncOutfitSeg(scr);
if (scr.dataset.screen === 'closet-share') syncShareSeg(scr);
buildStatePanel(scr, scr.dataset.screen);
}
/* 输入联动 */
document.addEventListener('input', function (e) {
var t = e.target;
if (!t) return;
var scr = t.closest && t.closest('.screen');
if (!scr) return;
if (t.classList.contains('oe-input') || t.classList.contains('oe-area')) {
var f = t.closest('.oe-field');
if (f) {
var c = $('.c', f);
var max = t.getAttribute('maxlength') || '0';
if (c) c.textContent = t.value.length + '/' + max;
}
if (scr.dataset.screen === 'outfit-edit') refreshSave(scr);
}
});
/* ============================================================
§J 启动
============================================================ */
buildIndex();
App.render();
})();
</script>
</body>
</html>