:root{
  --ink:#0E2338;
  --ink-2:#123A63;
  --gold:#C9A227;
  --gold-l:#E7C868;
  --bg:#F4F6FA;
  --card:#FFFFFF;
  --line:#E3E8F0;
  --line-2:#CFD9E7;
  --muted:#7A8798;
  --warn:#B7791F;
  --ok:#1F7A4D;
  --danger:#B23B3B;
  --radius:14px;
}
*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{
  font-family:"Microsoft YaHei","PingFang SC","Segoe UI",system-ui,-apple-system,sans-serif;
  background:var(--bg);color:var(--ink);font-size:14px;line-height:1.55;
  -webkit-font-smoothing:antialiased;
}
a{color:inherit}
select,textarea,input,button{font-family:inherit;font-size:inherit}

/* ============ 布局骨架 ============ */
.app{display:flex;min-height:100vh}

.sidebar{
  width:226px;flex:0 0 226px;height:100vh;position:sticky;top:0;
  background:linear-gradient(180deg,#0A1C30 0%,#123A63 100%);
  color:#fff;display:flex;flex-direction:column;padding:22px 16px 18px;
}
.logo{display:flex;align-items:center;gap:11px;padding:0 4px 20px;border-bottom:1px solid rgba(255,255,255,.09)}
.logo-mark{
  width:40px;height:40px;border-radius:11px;flex:0 0 40px;
  background:linear-gradient(135deg,#E7C868,#C9A227);
  color:#0A1C30;font-weight:700;font-size:19px;
  display:flex;align-items:center;justify-content:center;
}
.logo-name{font-size:16px;font-weight:700;letter-spacing:.5px}
.logo-sub{font-size:11px;color:#9DB4CE;letter-spacing:.3px}

.nav{display:flex;flex-direction:column;gap:5px;margin-top:20px}
.nav-item{
  position:relative;display:block;padding:11px 14px;border-radius:9px;
  color:#C3D3E6;font-size:14px;text-decoration:none;cursor:pointer;
  transition:background .15s,color .15s;user-select:none;
}
.nav-item:hover{background:rgba(255,255,255,.07);color:#fff}
.nav-item.active{background:rgba(201,162,39,.15);color:#F2D98C;font-weight:600}
.nav-item.active::before{
  content:"";position:absolute;left:0;top:9px;bottom:9px;width:3px;
  border-radius:0 3px 3px 0;background:var(--gold);
}

.side-foot{margin-top:auto;font-size:11px;color:#68809C;text-align:center;line-height:1.6}

.workspace{flex:1;min-width:0;display:flex;flex-direction:column}

.topbar{
  height:64px;flex:0 0 64px;background:#fff;border-bottom:1px solid var(--line);
  display:flex;align-items:center;justify-content:space-between;
  padding:0 28px;position:sticky;top:0;z-index:20;
}
.crumb{font-size:16px;font-weight:600;color:var(--ink)}

/* 顶栏左/右两组：.topbar 是 space-between —— 左侧品牌标识、右侧账号条。
   🔴 09-21 姜总走查：顶栏的**横向导航**与**引擎徽标**都已移除，顶栏只留这两样。
   横向导航原是为"首页隐藏侧栏后仍能回工作台"而加，现改由**登录态首页保留侧栏**解决；
   引擎徽标会把供应商名（扣子工作流）露给客户，属对外门面不该出现的信息。 */
.topbar-l{display:flex;align-items:center;gap:10px;min-width:0}
.topbar-r{display:flex;align-items:center}

.content{padding:26px 28px 64px;max-width:1620px;width:100%}

/* ============ 通用组件 ============ */
.btn{
  border:none;border-radius:9px;padding:11px 20px;font-size:14px;font-weight:600;
  cursor:pointer;transition:.15s;background:#E9EEF6;color:var(--ink);
}
.btn:hover{filter:brightness(.97)}
.btn:disabled{opacity:.5;cursor:not-allowed}
.btn.gold{background:linear-gradient(135deg,#E7C868,#C9A227);color:#20180A}
.btn.gold:hover{box-shadow:0 6px 16px rgba(201,162,39,.35)}
.btn.ghost{background:#fff;border:1px solid var(--line-2);color:var(--ink)}
.btn.ghost:hover{border-color:var(--gold);color:#8A6E15}
.btn.small{padding:7px 15px;font-size:13px;border-radius:8px}
.btn.block{display:block;width:100%;text-align:center;text-decoration:none}
.btn.lg{padding:14px 20px;font-size:15px}

.sec-title{
  display:flex;align-items:baseline;justify-content:space-between;
  font-size:16px;font-weight:700;margin:0 0 14px;
}
.sec-title span{font-size:12.5px;font-weight:400;color:var(--muted)}

.notice{
  background:#F1F5FB;border:1px solid var(--line);border-left:3px solid var(--ink-2);
  border-radius:9px;padding:11px 15px;font-size:13px;color:#3C5470;margin:0 0 18px;
}
.notice b{color:var(--ink)}
.notice.warn{background:#FFFBF0;border-color:#F0E2BE;border-left-color:var(--warn);color:#7A5B18}
.notice.ok{background:#F1FAF4;border-color:#CFE9D9;border-left-color:var(--ok);color:#1F6B47}

.foot-note{font-size:12px;color:var(--muted);text-align:center;margin-top:22px;line-height:1.8}

/* ============ 筛选条 ============ */
.filterbar{
  background:#fff;border:1px solid var(--line);border-radius:var(--radius);
  padding:14px 18px;display:flex;align-items:center;gap:22px;flex-wrap:wrap;margin-bottom:20px;
}
.fb-group{display:flex;align-items:center;gap:9px}
.fb-label{font-size:12.5px;color:var(--muted);white-space:nowrap}
.fb-group select,.fb-group input[type=text]{
  padding:8px 12px;border:1px solid var(--line-2);border-radius:8px;background:#fff;
  color:var(--ink);outline:none;font-size:13px;
}
.fb-group input[type=text]{width:190px}
.fb-group select:focus,.fb-group input:focus{border-color:var(--gold)}
.fb-spacer{flex:1}
.fb-count{font-size:13px;color:var(--muted)}
.fb-count b{color:var(--ink);font-size:15px}

/* ============ 模板网格 ============ */
.tpl-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(232px,1fr));gap:20px}
.tpl-card{
  background:#fff;border:1px solid var(--line);border-radius:var(--radius);
  overflow:hidden;cursor:pointer;transition:transform .18s,box-shadow .18s,border-color .18s;
  display:flex;flex-direction:column;
}
.tpl-card:hover{transform:translateY(-3px);box-shadow:0 14px 30px rgba(14,35,56,.13);border-color:#C6D6E8}
.tpl-thumb{position:relative;aspect-ratio:9/16;background:#0E2338;overflow:hidden;cursor:pointer}
.tpl-thumb img{width:100%;height:100%;object-fit:cover;display:block}
.tpl-mask{
  position:absolute;inset:0;background:linear-gradient(180deg,rgba(10,28,48,0) 40%,rgba(10,28,48,.78));
  opacity:0;transition:opacity .18s;display:flex;align-items:flex-end;justify-content:center;gap:10px;padding:14px;
}
.tpl-card:hover .tpl-mask{opacity:1}
.tpl-mask .go-btn{
  background:linear-gradient(135deg,#E7C868,#C9A227);color:#20180A;font-weight:700;font-size:13px;
  border-radius:8px;padding:9px 16px;white-space:nowrap;
}
.tpl-mask .go-btn.ghost{background:rgba(255,255,255,.92);color:var(--ink);font-weight:600}
.tpl-mask .go-btn.ghost:hover{background:#fff}
.tpl-badge{
  position:absolute;top:10px;left:10px;background:rgba(10,28,48,.72);color:#F2D98C;
  font-size:11px;padding:3px 9px;border-radius:20px;backdrop-filter:blur(4px);
}
.tpl-meta{padding:12px 14px 14px;display:flex;flex-direction:column;gap:7px;cursor:pointer}
.tpl-name{font-size:14px;font-weight:600;line-height:1.4;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tpl-row{display:flex;align-items:center;justify-content:space-between;gap:10px;font-size:12.5px;color:var(--muted)}
.tpl-spot{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* 热度 · 火焰分级（不显示数值，火苗越多越热） */
.hot{display:inline-flex;align-items:center;gap:2px;line-height:1}
.hot svg{width:13px;height:13px;flex:none;fill:#D5DEE9}
.hot svg.on{fill:#E08A2C}
.modal-info .mi .hot svg{width:14px;height:14px}

.empty{
  background:#fff;border:1px dashed var(--line-2);border-radius:var(--radius);
  padding:60px 20px;text-align:center;color:var(--muted);
}

/* ============ 制作台（左右分栏） ============ */
.studio{display:grid;grid-template-columns:minmax(380px,1fr) minmax(470px,1.08fr);gap:24px;align-items:start}
.studio-left{position:sticky;top:88px;display:flex;flex-direction:column;gap:18px}
.panel{background:#fff;border:1px solid var(--line);border-radius:var(--radius);padding:20px 22px}
.panel-title{font-size:14.5px;font-weight:700;margin:0 0 14px;display:flex;align-items:center;gap:8px}
.panel-title::before{content:"";width:3px;height:14px;border-radius:2px;background:var(--gold)}

.player{
  width:100%;display:block;border-radius:var(--radius);background:#000;
  max-height:600px;object-fit:contain;
}
.player-wrap{background:#0E2338;border-radius:var(--radius);overflow:hidden;display:flex;align-items:center;justify-content:center}

.info-list{display:flex;flex-direction:column;gap:10px}
.info-row{display:flex;justify-content:space-between;font-size:13px;color:var(--muted)}
.info-row b{color:var(--ink);font-weight:600}
.info-row.total{border-top:1px dashed var(--line-2);padding-top:11px;margin-top:3px}
.info-row.total b{color:#A8801A;font-size:18px}

.flow{display:flex;flex-direction:column;gap:9px}
.flow-item{display:flex;gap:10px;font-size:12.5px;color:var(--muted);line-height:1.5}
.flow-no{
  flex:0 0 20px;height:20px;border-radius:50%;background:#EDF2F9;color:var(--ink-2);
  font-size:11px;font-weight:700;display:flex;align-items:center;justify-content:center;
}
.flow-item.on{color:var(--ink)}
.flow-item.on .flow-no{background:linear-gradient(135deg,#E7C868,#C9A227);color:#20180A}

/* 步骤块 */
.step{border-top:1px solid var(--line);padding-top:16px;margin-top:16px}
.step:first-child{border-top:none;padding-top:0;margin-top:0}
.step-head{display:flex;align-items:center;gap:9px;margin-bottom:11px}
.step-no{
  width:22px;height:22px;flex:0 0 22px;border-radius:50%;
  background:#EDF2F9;color:var(--ink-2);font-size:12px;font-weight:700;
  display:flex;align-items:center;justify-content:center;
}
.step-head .st{font-size:13.5px;font-weight:600}
.step-head .req{font-size:11.5px;color:var(--danger);font-weight:400}
.step-head .opt{font-size:11.5px;color:var(--muted);font-weight:400}
.step-hint{font-size:12px;color:var(--muted);margin-top:9px;line-height:1.6}

/* 照片闸门提示（2026-09-19）：把服务端给出的**具体重拍指引**原样交给客户，
   而不是弹一句"照片不合格"打发人。三档：busy 检查中 / warn 放行但有提示 / error 已拦截。 */
.photo-notice{
  margin-top:10px;border-radius:10px;padding:10px 13px;font-size:12.5px;line-height:1.6;
  border-left:3px solid var(--line-2);background:#F7F9FC;color:#42566E;
}
.photo-notice b{display:block;font-size:12px;font-weight:600;margin-bottom:3px}
.photo-notice span{color:var(--muted)}
.photo-notice.busy{border-left-color:var(--gold);background:#FDFAF0}
.photo-notice.busy b{color:#8A6E15}
.photo-notice.warn{border-left-color:var(--warn);background:#FDF7EC}
.photo-notice.warn b{color:var(--warn)}
.photo-notice.error{border-left-color:var(--danger);background:#FDF2F2}
.photo-notice.error b{color:var(--danger)}
.photo-notice.error span{color:#8A4B4B}

.chip-row{display:flex;flex-wrap:wrap;gap:8px}
.chip{
  border:1px solid var(--line-2);background:#fff;border-radius:8px;
  padding:7px 14px;font-size:12.5px;color:#42566E;cursor:pointer;transition:.15s;user-select:none;
}
.chip:hover{border-color:var(--gold);color:#8A6E15}
.chip.active{background:linear-gradient(135deg,#E7C868,#C9A227);border-color:#C9A227;color:#20180A;font-weight:600}

.drop{
  border:1.6px dashed #C6D4E6;border-radius:12px;background:#FAFCFF;
  padding:22px 16px;text-align:center;cursor:pointer;transition:.15s;position:relative;
}
.drop:hover,.drop.over{border-color:var(--gold);background:#FFFDF5}
.drop-title{font-size:13px;color:var(--ink);font-weight:600}
.drop-sub{font-size:12px;color:var(--muted);margin-top:5px}
.drop.has{border-style:solid;border-color:#DCE5F0;background:#fff;padding:12px;display:flex;align-items:center;gap:14px;text-align:left}
.drop.has img{width:74px;height:96px;object-fit:cover;border-radius:9px;border:1px solid var(--line)}
.drop.has .dt{font-size:13px;font-weight:600}
.drop.has .ds{font-size:12px;color:var(--muted);margin-top:4px}
.thumb-mini{width:46px;height:60px;object-fit:cover;border-radius:7px;border:1px solid var(--line)}

textarea{
  width:100%;min-height:88px;resize:vertical;border:1px solid var(--line-2);
  border-radius:10px;padding:11px 13px;font-size:13px;line-height:1.6;
  color:var(--ink);outline:none;background:#fff;
}
textarea:focus{border-color:var(--gold)}

/* ============ 二选一（分段控件）：服装 / 背景音乐 的第一层选择 ============ */
.seg{
  display:grid;grid-template-columns:1fr 1fr;gap:8px;background:#F3F7FC;
  border:1px solid var(--line);border-radius:11px;padding:5px;
}
.seg-item{
  text-align:center;padding:10px 8px;border-radius:8px;font-size:13px;color:#42566E;
  cursor:pointer;transition:.15s;user-select:none;line-height:1.35;
}
.seg-item:hover{background:#E9F0FA}
.seg-item.active{
  background:#fff;color:var(--ink);font-weight:600;
  box-shadow:0 1px 4px rgba(16,42,72,.12);border:1px solid #E2EAF4;padding:9px 7px;
}
.seg-item .seg-sub{display:block;font-size:11.5px;font-weight:400;color:var(--muted);margin-top:3px}

/* ============ 服装库九宫格（缩略图预览 + 放大） ============ */
.lib-grid{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(122px,1fr));
  gap:12px;margin-top:14px;
}
.lib-card{
  border:1px solid var(--line-2);border-radius:11px;background:#fff;overflow:hidden;
  cursor:pointer;transition:.15s;position:relative;
}
.lib-card:hover{border-color:var(--gold);box-shadow:0 4px 14px rgba(16,42,72,.09)}
.lib-card.active{border-color:#C9A227;box-shadow:0 0 0 2px rgba(201,162,39,.18)}
.lib-thumb{position:relative;background:#0E2338;aspect-ratio:3/4;overflow:hidden}
.lib-thumb img{width:100%;height:100%;object-fit:cover;display:block}
.lib-zoom{
  position:absolute;right:7px;bottom:7px;background:rgba(10,28,48,.72);color:#fff;
  font-size:11px;border-radius:6px;padding:3px 8px;opacity:0;transition:.15s;
}
.lib-thumb:hover .lib-zoom{opacity:1}
.lib-check{
  position:absolute;left:7px;top:7px;width:21px;height:21px;border-radius:50%;
  background:linear-gradient(135deg,#E7C868,#C9A227);color:#20180A;
  font-size:12px;font-weight:700;display:flex;align-items:center;justify-content:center;
}
.lib-meta{padding:9px 10px 11px}
.lib-meta .lib-name{font-size:12.5px;font-weight:600;line-height:1.4}
.lib-meta .lib-tag{
  display:inline-block;margin-top:6px;font-size:11px;color:#7A8798;
  background:#F1F5FB;border-radius:20px;padding:2px 9px;
}
.lib-empty{
  margin-top:12px;border:1px dashed var(--line-2);border-radius:11px;background:#FAFCFF;
  padding:22px 16px;text-align:center;font-size:12.5px;color:var(--muted);
}

/* ============ 背景音乐库（可试听） ============ */
.bgm-list{display:flex;flex-direction:column;gap:8px;margin-top:14px}
.bgm-row{
  display:flex;align-items:center;gap:12px;border:1px solid var(--line-2);border-radius:11px;
  background:#fff;padding:10px 13px;cursor:pointer;transition:.15s;
}
.bgm-row:hover{border-color:var(--gold)}
.bgm-row.active{border-color:#C9A227;background:#FFFCF3;box-shadow:0 0 0 2px rgba(201,162,39,.15)}
.bgm-play{
  flex:0 0 34px;width:34px;height:34px;border-radius:50%;border:none;cursor:pointer;
  background:linear-gradient(135deg,#E7C868,#C9A227);color:#20180A;font-size:12px;line-height:1;
  display:flex;align-items:center;justify-content:center;transition:.15s;
}
.bgm-play:hover{filter:brightness(1.06)}
.bgm-main{flex:1;min-width:0}
.bgm-main .bgm-name{font-size:13px;font-weight:600}
.bgm-main .bgm-mood{font-size:11.5px;color:var(--muted);margin-top:3px}
.bgm-sel{font-size:11.5px;font-weight:600;color:#A8801A;white-space:nowrap}
.bgm-eq{display:inline-flex;align-items:flex-end;gap:2px;height:12px;margin-left:8px}
.bgm-eq i{width:2.5px;background:#C9A227;border-radius:2px;animation:eq .9s ease-in-out infinite}
.bgm-eq i:nth-child(1){height:6px;animation-delay:0s}
.bgm-eq i:nth-child(2){height:11px;animation-delay:.15s}
.bgm-eq i:nth-child(3){height:8px;animation-delay:.3s}
@keyframes eq{0%,100%{transform:scaleY(.5)}50%{transform:scaleY(1)}}

/* ============ 图片放大预览弹窗 ============ */
.modal-box.imgbox{width:min(560px,94vw);align-items:center}
.modal-box.imgbox .imgbox-img{
  width:100%;max-height:68vh;object-fit:contain;border-radius:12px;background:#0E2338;
}

/* ============ 生成中 ============ */
.center-stage{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:70px 20px;text-align:center}
.spinner{
  width:58px;height:58px;border-radius:50%;
  border:4px solid #E4EBF4;border-top-color:var(--gold);
  animation:spin 1s linear infinite;margin-bottom:26px;
}
@keyframes spin{to{transform:rotate(360deg)}}
.bar{
  width:min(560px,86vw);height:7px;border-radius:20px;background:#E7EDF6;
  overflow:hidden;position:relative;margin:22px 0 10px;
}
.bar::after{
  content:"";position:absolute;top:0;bottom:0;width:38%;border-radius:20px;
  background:linear-gradient(90deg,#E7C868,#C9A227);
  animation:flow 1.5s ease-in-out infinite;
}
@keyframes flow{0%{left:-40%}100%{left:100%}}
.status-title{font-size:19px;font-weight:700;margin-bottom:9px}
.status-sub{font-size:13px;color:var(--muted);line-height:1.9}
.timer{font-size:26px;font-weight:700;color:var(--ink-2);margin-top:16px;font-variant-numeric:tabular-nums}
/* 已完成（停留页，不自动跳转） */
.done-mark{
  width:64px;height:64px;border-radius:50%;margin-bottom:24px;
  display:flex;align-items:center;justify-content:center;
  font-size:32px;font-weight:700;line-height:1;
  color:#fff;background:linear-gradient(135deg,#3AA06A,#1F7A4D);
  box-shadow:0 8px 22px rgba(31,122,77,.28);
}
.done-actions{display:flex;flex-wrap:wrap;gap:12px;justify-content:center;margin-top:28px}

/* ============ 成片结果 ============ */
.result{display:grid;grid-template-columns:minmax(400px,1fr) minmax(360px,.82fr);gap:24px;align-items:start}
.result-side{display:flex;flex-direction:column;gap:14px}
.kv{display:flex;justify-content:space-between;font-size:13px;padding:8px 0;border-bottom:1px solid var(--line)}
.kv:last-child{border-bottom:none}
.kv .k{color:var(--muted)}

/* ============ 订单表格 ============ */
.tbl-wrap{background:#fff;border:1px solid var(--line);border-radius:var(--radius);overflow:hidden}
table.tbl{width:100%;border-collapse:collapse}
table.tbl th{
  text-align:left;font-size:12.5px;font-weight:600;color:var(--muted);
  background:#F8FAFD;padding:12px 16px;border-bottom:1px solid var(--line);white-space:nowrap;
}
table.tbl td{padding:13px 16px;border-bottom:1px solid #EFF3F8;font-size:13px;vertical-align:middle}
table.tbl tr:last-child td{border-bottom:none}
table.tbl tr:hover td{background:#FAFCFF}
.mono{font-family:Consolas,Menlo,monospace;font-size:12px;color:var(--muted)}
.badge{
  display:inline-block;border-radius:20px;padding:3px 11px;font-size:11.5px;font-weight:600;white-space:nowrap;
}
.badge.success{background:#EAF7F0;color:#1F7A4D}
.badge.generating{background:#FFF6E3;color:#A8801A}
.badge.paid{background:#EDF2F9;color:#42566E}
.badge.refunded{background:#FBEEEE;color:#B23B3B}

/* ============ 任务列表工具条 ============ */
.orders-bar{
  background:#fff;border:1px solid var(--line);border-radius:var(--radius);
  padding:12px 16px;display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin-bottom:18px;
}
.ob-chips{display:flex;gap:8px;flex-wrap:wrap}
.ob-spacer{flex:1}
.chip.sm{padding:6px 13px;font-size:12.5px;display:inline-flex;align-items:center;gap:6px}
.chip-n{
  font-size:11.5px;font-weight:700;color:#7A8798;background:#EFF3F9;
  border-radius:20px;padding:1px 7px;line-height:1.5;
}
.chip.active .chip-n{background:rgba(32,24,10,.16);color:#20180A}
.ob-at{font-size:12.5px;color:var(--muted);white-space:nowrap}
.live{display:inline-flex;align-items:center;gap:7px;font-size:12.5px;color:#A8801A;white-space:nowrap}
.live i{
  width:7px;height:7px;border-radius:50%;background:#C9A227;
  animation:pulse 1.3s ease-in-out infinite;
}
@keyframes pulse{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.35;transform:scale(.7)}}
.nowrap{white-space:nowrap}

/* 统计卡 */
.wallet-cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:16px;margin-bottom:22px}
.stat{
  background:#fff;border:1px solid var(--line);border-radius:var(--radius);padding:17px 19px;
}
.stat .sl{font-size:12.5px;color:var(--muted)}
.stat .sv{font-size:24px;font-weight:700;margin-top:6px;color:var(--ink)}
.stat .sv.gold{color:#A8801A}

/* 说明页 */
.doc{background:#fff;border:1px solid var(--line);border-radius:var(--radius);padding:26px 30px;max-width:920px}
.doc h3{font-size:15px;margin:24px 0 10px;padding-left:10px;border-left:3px solid var(--gold)}
.doc h3:first-child{margin-top:0}
.doc p{margin:0 0 10px;color:#42566E;font-size:13.5px;line-height:1.85}
.doc ol,.doc ul{margin:0 0 10px;padding-left:22px;color:#42566E;font-size:13.5px;line-height:1.95}
.doc code{background:#F1F5FB;border-radius:5px;padding:1px 6px;font-size:12.5px;font-family:Consolas,Menlo,monospace}

/* 返回条 */
.backbar{display:flex;align-items:center;gap:14px;margin-bottom:18px}
.back-link{
  display:inline-flex;align-items:center;gap:6px;font-size:13.5px;color:var(--ink-2);
  cursor:pointer;user-select:none;font-weight:600;
}
.back-link:hover{color:var(--gold)}
.crumb-mini{font-size:13px;color:var(--muted)}

/* ============ 模板预览弹窗 ============ */
.modal{position:fixed;inset:0;z-index:80;display:flex;align-items:center;justify-content:center;padding:36px 20px}
.modal-mask{position:absolute;inset:0;background:rgba(10,28,48,.74)}
.modal-box{
  position:relative;background:#fff;border-radius:16px;box-shadow:0 30px 70px rgba(10,28,48,.42);
  width:min(900px,96vw);max-height:92vh;overflow:auto;padding:18px 20px 20px;
  display:flex;flex-direction:column;gap:14px;
}
.modal-head{display:flex;align-items:center;justify-content:space-between;gap:14px}
.modal-title{font-size:16px;font-weight:700}
.modal-x{
  border:none;background:#F1F5FB;color:var(--muted);width:30px;height:30px;flex:0 0 30px;
  border-radius:8px;cursor:pointer;font-size:13px;line-height:1;
}
.modal-x:hover{background:#E5EBF5;color:var(--ink)}
.modal-box .player-wrap{max-height:62vh}
.modal-info{display:flex;flex-wrap:wrap;gap:10px}
.modal-info .mi{
  display:inline-flex;align-items:center;gap:7px;font-size:12.5px;color:var(--ink);
  background:#F7F9FC;border:1px solid var(--line);border-radius:8px;padding:6px 12px;
}
.modal-info .mi b{font-weight:400;color:var(--muted);font-size:12px}

@media (max-width:1180px){
  .studio{grid-template-columns:1fr}
  .studio-left{position:static}
  .result{grid-template-columns:1fr}
}

/* ============ 账号条（登录态 / 所属区域）============ */
/* 地域随账号绑定，界面不提供地域切换入口 */
.account{margin-left:14px;display:flex;align-items:center;gap:10px}
.acct-guest{font-size:12.5px;color:var(--muted)}
.acct-name{font-size:13.5px;font-weight:600;color:var(--ink);max-width:180px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.acct-prov{
  display:inline-flex;align-items:center;font-size:12px;font-weight:600;color:var(--ink-2);
  background:#EEF3FA;border:1px solid var(--line);border-radius:999px;padding:4px 11px;
}
.acct-warn{font-size:12px;font-weight:600;color:var(--warn);background:#FBF4E6;border:1px solid #EBD9AE;border-radius:999px;padding:4px 10px}
/* 账户生成次数（2026-09-22 试运行商务额度）：只报"剩余 N 条"，永不出现金额/余额。
   out = 已用完 ⇒ 换警示色，提示该续购了（见 app.js 的 renderAccount / quotaCheck） */
.acct-quota{
  display:inline-flex;align-items:center;font-size:12px;font-weight:600;color:var(--ok);
  background:#EAF6EF;border:1px solid #CBE6D8;border-radius:999px;padding:4px 11px;
  white-space:nowrap;
}
.acct-quota.out{color:var(--danger);background:#FBEDED;border-color:#EFCFCF}
.acct-btn{
  font-size:12.5px;font-weight:600;color:#fff;background:var(--ink);border:0;border-radius:8px;
  padding:6px 14px;cursor:pointer;font-family:inherit;
}
.acct-btn:hover{background:var(--ink-2)}
.acct-btn.ghost{background:#EEF3FA;color:var(--ink-2);border:1px solid var(--line)}
.acct-btn.ghost:hover{background:#E3EAF4}

/* ============ 登录层 ============ */
.login-mask{
  position:fixed;inset:0;z-index:120;display:flex;align-items:center;justify-content:center;
  background:rgba(10,28,48,.72);padding:32px 20px;
}
.login-mask[hidden]{display:none}
.login-card{
  position:relative;width:100%;max-width:400px;background:#fff;border-radius:16px;
  padding:26px 26px 28px;box-shadow:0 24px 60px rgba(10,28,48,.32);
}
/* 关闭出口（姜总 09-21：登录/注册窗体打开后原先没有退出的口子）
   三个入口共用同一个 ✕：微信扫码 / 手机号 / 商户资料。 */
.login-x{
  position:absolute;right:12px;top:12px;width:30px;height:30px;border-radius:8px;
  display:flex;align-items:center;justify-content:center;
  border:1px solid transparent;background:transparent;color:var(--muted);
  font-size:14px;line-height:1;cursor:pointer;font-family:inherit;
  transition:background .15s,color .15s;
}
.login-x:hover{background:#F1F4F9;border-color:var(--line);color:var(--ink)}
.login-x:focus-visible{outline:2px solid var(--gold);outline-offset:1px}
.login-head{display:flex;align-items:center;gap:12px;margin-bottom:20px}
.login-title{font-size:17px;font-weight:700;color:var(--ink)}
.login-sub{font-size:12.5px;color:var(--muted)}
.login-sub2{font-size:13.5px;color:var(--ink-2);margin-bottom:14px;font-weight:600}
.login-qr{width:200px;height:200px;display:block;margin:0 auto}
.login-loading,.login-err{font-size:13px;color:var(--muted);text-align:center;padding:18px 0}
.login-err{color:#B4232A}
.login-note{font-size:12px;color:var(--muted);line-height:1.7;text-align:center;margin-top:12px}

/* 双线登录：微信扫码 / 手机号密码 */
.login-tabs{display:flex;gap:8px;margin-bottom:16px}
.ltab{
  flex:1;padding:9px 0;border:1px solid var(--line-2);border-radius:9px;background:#fff;
  color:var(--muted);font-size:14px;cursor:pointer;transition:all .15s;
}
.ltab:hover{border-color:var(--ink-2);color:var(--ink-2)}
.ltab.on{background:var(--ink-2);border-color:var(--ink-2);color:#fff;font-weight:600}

/* 开发态占位二维码：明确标明未接入微信，避免被误认为真二维码 */
.dev-qr{display:flex;justify-content:center}
.dev-qr-box{
  width:180px;height:180px;border:2px dashed var(--line-2);border-radius:12px;background:#F7F9FC;
  position:relative;
}
.dev-qr-box::after{
  content:"开发态 · 未接入微信";position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  font-size:11px;color:var(--muted);white-space:nowrap;
}
.login-card .fld{display:block;margin-bottom:12px}
.login-card .fld span{display:block;font-size:12.5px;color:var(--ink-2);margin-bottom:6px;font-weight:600}
.login-card .fld input,.login-card .fld select{
  width:100%;height:38px;padding:0 12px;font-size:13.5px;font-family:inherit;
  border:1px solid var(--line);border-radius:8px;background:#fff;color:var(--ink);outline:none;box-sizing:border-box;
}
.login-card .fld input:focus,.login-card .fld select:focus{border-color:var(--gold)}

/* ============ 首页（纯展示门面）============ */
/* 🔴 姜总 09-21 三条定调，本段按此重写：
   ① 信息尽量在一屏内展示完整 —— **全部纵向尺寸用 vh 驱动**（字号也用 clamp(…, vh, …)），
      body.view-home 下把内容区高度锁死为 calc(100vh - 顶栏64px)，常规笔记本视口不出纵向滚动条；
   ② 首页只是展示页、不带任何功能点 —— 本页**零按钮、零输入框**（顶栏导航也已移除）；
   ③ 结构参照主流 AIGC 平台首页：主视觉主张 → 作品墙（能力分块卡片已按第四次走查删除）。
   ⚠️ 演示版纪律：本页不出现任何金额/费用/余额/支付字样。

   🔴 一条实测出来的硬规矩（09-21，无头 Edge 1440×900 截图发现）：
   **图片一律用 vh 常量定高，绝不用 height:100% 去接父容器的高度。**
   flex 行（align-items:center + 子项比例盒）里的 height:100% 会退化成 auto ⇒
   图片按自身固有尺寸撑开 ⇒ 把 Hero 压扁（副标题下的标签被裁掉）、
   把作品墙的左右两栏文字压住。改成 vh 常量后，宽度由 9:16 推出，完全可控。 */
.home{display:flex;flex-direction:column;gap:clamp(12px,2vh,22px);flex:1 1 auto;min-height:0}

/* —— 主视觉：左主张 / 右成片 ——
   🔴 第五次走查（09-21）：「上面部分的比例不用占这么大」⇒ 由 1.3 : 1 压到 0.9 : 1.35，
      同时把标题字号、行距、内边距、右侧两张示范图一起收一档（只改 flex 不改内部，
      会出现"框小了但内容没小"⇒ 内容溢出被 overflow:hidden 裁掉）。 */
.home-hero{
  flex:0.9 1 auto;min-height:168px;
  display:flex;gap:clamp(18px,2vw,32px);align-items:center;
  background:linear-gradient(135deg,#0A1C30 0%,#123A63 100%);
  border-radius:var(--radius);padding:clamp(14px,2vh,22px) clamp(20px,2.2vw,38px);
  color:#fff;overflow:hidden;
}
.home-hero-l{flex:1 1 auto;min-width:0}
.home-kicker{font-size:clamp(11px,1.25vh,12.5px);letter-spacing:1.4px;color:#9DB4CE;margin-bottom:clamp(7px,1.1vh,11px)}
.home-title{margin:0 0 clamp(7px,1vh,12px);font-weight:700;letter-spacing:.5px;font-size:clamp(23px,4.1vh,36px);line-height:1.22}
.home-sub{margin:0 0 clamp(9px,1.6vh,16px);font-size:clamp(12px,1.55vh,14.5px);color:#C3D3E6;line-height:1.7;max-width:600px}
.home-chips{display:flex;gap:9px;flex-wrap:wrap}
.chip{
  font-size:clamp(11px,1.3vh,12.5px);color:#E6EEF8;letter-spacing:.4px;
  padding:5px 12px;border-radius:999px;
  border:1px solid rgba(231,200,104,.34);background:rgba(231,200,104,.09);
}
.home-hero-r{align-self:stretch;flex:0 0 auto;display:flex;gap:clamp(10px,1vw,14px);align-items:center}
.home-shot-main,.home-shot-sub{border-radius:12px;overflow:hidden;box-shadow:0 12px 30px rgba(0,0,0,.35);flex:0 0 auto}
.home-shot-main{height:clamp(104px,27vh,262px);max-height:100%;aspect-ratio:9/16;border:2px solid rgba(255,255,255,.16)}
.home-shot-sub{height:clamp(78px,19.5vh,190px);max-height:100%;aspect-ratio:9/16;border:2px solid rgba(255,255,255,.12)}
.home-shot-main img,.home-shot-sub img{width:100%;height:100%;object-fit:cover;display:block}

/* —— 能力分块（原 4 张 01~04 卡片）已按姜总 09-21 四次走查删除 ——
   能力表达改由 Hero 下方 `.home-chips` 三个标签承担；此处不留规则，避免误加回。
   首页现为**上下两块**：主视觉（hero）+ 作品墙（gallery）。 */

/* —— 作品墙：地区卡轮播（轨道 / 地区卡 / 卡内缩略图 / 圆点）——
   🔴 第五次走查（09-21）：「下面的部分做成轮播的形式」；
      第七次走查（09-21）：「按地区来轮播 —— 将不同地区热度排名靠前的 5 个模板缩略图
      做成一个卡片来轮播；现在只有云南，那就先制作云南的轮播卡片」。
   形态：轨道里横排若干**地区卡**，每 3.2s 左移**一张卡** —— 因为卡宽＝容器宽，**一屏正好一张卡**。
     "尾部克隆一份 + 无动画归零"的无缝循环只在 ≥2 个地区时启用；
     当前只有云南 ⇒ 单卡静态展示（代码结构不变，素材补齐即自动变多卡轮播）。
   🔴 卡片高 / 缩略图高都由 JS 实测后写进 --card-h / --thumb-h（比 vh 常量更贴合容器，
     也避开 height:100% + aspect-ratio 在 flex 行里退化成 auto 的坑）；下面的 clamp 是**兜底值** ——
     DOM stub / 容器隐藏时 JS 测不到高度，就退回这份 vh 值，绝不出现"0 高度卡片"。 */
.home-gallery{
  flex:1.35 1 auto;min-height:170px;
  display:flex;align-items:center;gap:clamp(14px,2vw,28px);
  background:var(--card);border:1px solid var(--line);border-radius:var(--radius);
  padding:clamp(12px,1.7vh,17px) clamp(16px,1.6vw,24px);
}
.gal-mid{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:clamp(8px,1.1vh,11px)}
.gal-view{position:relative;flex:1 1 auto;width:100%;min-width:0;min-height:0;overflow:hidden}
/* 🔴 这一行里有两处不能动（09-21 实测踩过）：
   ① `width:100%` 不能换成 `margin:0 auto` 居中 —— `.gal-mid` 是 **flex 纵向容器**，
      auto margin 会**接管横向对齐**、宽度随即退化成 max-content（实测 963px → 1180px）。
   ② `min-height:0` 不能删 —— 纵向 flex 子项的 min-height 默认是 auto，会被内容顶开；
      一被顶开，卡片高就从"容器分配"变成"内容撑开"，一屏就锁不住了。
   ⚠️ 第七次走查**删掉了原来的 `max-width:1180`**：那是给"卡宽由高度推出、太宽会同屏看到克隆"
      当安全阀用的；改成地区卡后卡宽恒等于本容器宽，该上限已无对象，留着反而让作品墙比 Hero
      窄一截、上下两块对不齐。宽度方向现在由 galFit() 守 —— 守的是卡里那一排缩略图。 */
.gal-track{
  /* 🔴 这两个尺寸变量都只是**无 JS 时的兜底**：正常由 JS 实测后写成内联值（优先级更高）。
     但兜底不能省 —— DOM stub / 容器被隐藏时 JS 测不到高，得靠它们避免"0 高度卡片"。 */
  --card-h:clamp(180px,48vh,560px);       /* 卡片高（JS 用实测 gal-view 高覆盖） */
  --thumb-h:clamp(100px,40vh,460px);      /* 卡内缩略图高（JS 用实测 .reg-thumbs 高覆盖） */
  display:flex;align-items:center;gap:clamp(10px,.9vw,14px);
  transition:transform .62s cubic-bezier(.4,.05,.2,1);will-change:transform;
}

/* —— 地区卡：**一张卡 = 一个地区热度 TOP5 的缩略图横排**，轮播的单元是整张卡 ——
   🔴 卡宽恒等于轨道宽（= gal-view 宽）⇒ 同屏永远只看得见一张卡，
      "同屏出现某张封面和它的克隆"这个老问题从根上消失（不再是靠限宽压住的）。 */
.reg-card{
  flex:0 0 auto;width:100%;
  height:var(--card-h);              /* 🔴 必须显式定高：没有它 .reg-thumbs 的 flex:1 会退化成 0 高 */
  display:flex;flex-direction:column;
  padding:clamp(10px,1.5vh,16px) clamp(12px,1.3vw,20px);
  background:var(--bg);border:1px solid var(--line);border-radius:12px;
}
.reg-head{display:flex;align-items:baseline;gap:9px;margin-bottom:clamp(6px,1vh,10px)}
/* 地区名是这张卡的**唯一身份标识**（卡里只有它和缩略图），所以给它一根金色竖条 + 更大字号：
   与缩略图左上角的名次角标同色系，一眼能建立"这是某个地区的热门榜"的读法。 */
.reg-name{font-size:clamp(15px,2.4vh,21px);font-weight:700;color:var(--ink);letter-spacing:.5px}
.reg-name::before{
  content:'';display:inline-block;width:4px;height:.95em;margin-right:8px;
  vertical-align:-.08em;border-radius:2px;background:var(--gold);
}
.reg-sub{font-size:clamp(11px,1.5vh,13px);color:var(--muted);letter-spacing:.3px}
/* 🔴 `.reg-thumbs` 必须是 `flex:1 1 0`（basis **0**，不是 auto）＋ `min-height:0` ＋ `overflow:hidden`：
   这样它的高**只由 flex 分配、与内容无关** ⇒ JS 量一次就收敛。
   若改成 `flex:1 1 auto` 或去掉 min-height，缩略图一变大会反过来把它撑高 ⇒ 测量振荡（越量越大）。 */
.reg-thumbs{
  flex:1 1 0;min-height:0;overflow:hidden;
  display:flex;gap:clamp(8px,.8vw,14px);justify-content:center;align-items:center;
}
.reg-thumb{
  position:relative;flex:0 0 auto;margin:0;
  height:var(--thumb-h);aspect-ratio:9/16;      /* 高定死、宽由 9:16 推出（别写 width:100% 或 height:100%） */
  border-radius:9px;overflow:hidden;border:1px solid var(--line);background:#EEF2F8;
}
.reg-thumb img{width:100%;height:100%;object-fit:cover;display:block}
.reg-rank{
  position:absolute;top:0;left:0;z-index:1;
  min-width:19px;height:19px;padding:0 5px;margin:0;
  display:flex;align-items:center;justify-content:center;
  font-style:normal;font-size:11px;font-weight:700;line-height:1;
  color:#3A2E10;background:rgba(231,200,104,.94);border-bottom-right-radius:8px;
}
.reg-spot{
  position:absolute;left:0;right:0;bottom:0;z-index:1;margin:0;
  padding:12px 5px 5px;text-align:center;
  font-size:clamp(10px,1.25vh,11.5px);line-height:1.2;color:#fff;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  background:linear-gradient(to top,rgba(6,16,28,.8),rgba(6,16,28,0));
}
/* 🔴 轮播控件一律 <span>/<i>，**不得用 <button>**：H1e 断言「首页内容区零按钮」，
   且首页是纯展示页 —— 轮播控件只服务展示，不是业务入口。 */
.gal-arrow{
  position:absolute;top:50%;transform:translateY(-50%);z-index:2;
  width:30px;height:30px;border-radius:50%;cursor:pointer;user-select:none;
  display:flex;align-items:center;justify-content:center;
  font-size:17px;line-height:1;color:var(--ink-2);
  background:rgba(255,255,255,.94);border:1px solid var(--line);
  box-shadow:0 6px 16px rgba(14,35,56,.14);
  opacity:0;transition:opacity .18s;         /* 默认隐去，鼠标进区才出现（纯展示页别挂一堆控件） */
}
.gal-view:hover .gal-arrow{opacity:1}
.gal-arrow.prev{left:2px}
.gal-arrow.next{right:2px}
.gal-dots{display:flex;gap:7px;justify-content:center;align-items:center}
.gal-dot{width:6px;height:6px;border-radius:50%;background:var(--line-2);cursor:pointer;transition:background .2s,width .2s}
.gal-dot.on{width:18px;border-radius:3px;background:var(--gold)}

/* 未登录访客的"侧栏入口弱化"规则已移除：访客在首页时侧栏就被隐藏（见下），而访客进不了
   其它视图（登录门会弹登录层），故这条规则已无作用对象 —— 留着只会误导成"访客会看到侧栏"。 */

/* ============ 首页满宽（不显示左侧导航栏）============ */
/* 姜总 09-21：首页是**对外门面**，不应挂着工作台的侧边导航。
   故访客看到的首页整页满宽：隐藏 .sidebar、.app 由 flex 改块级、内容区居中。
   🔴 满宽规则**必须限定 .guest（访客态）**，这是顶栏导航被移除后的必然要求：
      访客在首页时侧栏本就无用（进任何业务视图都会弹登录层），隐藏它 ⇒ 干净的对外门面；
      登录用户点侧栏「首页」时**保留侧栏** ⇒ 页面上始终有回工作台的入口，不会走成死路。
      若两态都隐藏侧栏，登录用户一旦落到首页就被困住（首页零按钮、顶栏也已无导航）。
   其它视图（模板/任务/说明/制作台）保持原来的侧栏布局。 */
body.view-home.guest .app{display:block}
body.view-home.guest .sidebar{display:none}
body.view-home .content{
  margin:0 auto;
  height:calc(100vh - 64px);              /* 一屏 = 视口 - 顶栏 */
  padding:clamp(12px,1.8vh,20px) 28px;
  display:flex;flex-direction:column;
  overflow:hidden;                        /* 一屏展示：不出纵向滚动条 */
}

/* 兜底：视口过矮时"锁一屏"会裁掉内容 —— 此时宁可恢复滚动，也不要把信息吃掉 */
@media (max-height:640px){
  body.view-home .content{height:auto;min-height:0;overflow:auto}
  .home-hero{min-height:0}
  .gal-track{--card-h:clamp(150px,44vh,340px);--thumb-h:clamp(80px,30vh,250px)}   /* 矮屏：卡片跟着收，别把圆点挤出可视区 */
}
@media (max-width:1280px){
  .home-hero-r{display:none}
  /* ⚠️ 这个断点曾长期兼职"压住同屏可见张数"（靠保留 .gal-r 脚注占住宽度，1280×720 实测过 5.63 张）。
     那件事第六次走查交给了 galFit()、第七次走查随"地区卡"一起消失了 —— 卡宽恒等于容器宽，
     同屏永远只有一张卡。所以这里现在只剩"隐藏 Hero 右图"一件事，改起来是安全的。
     ⚠️ 但仍要跑 `node tools/shot-home.cjs` 复核：**卡内那排缩略图会不会被裁**，只有真实渲染看得见。 */
}
@media (max-width:1080px){
  .home-hero{flex-direction:column;align-items:flex-start}
  .home-gallery{flex-direction:column;align-items:stretch}
  .gal-mid{width:100%}
  .gal-track{--card-h:clamp(150px,40vh,360px);--thumb-h:clamp(80px,26vh,260px)}
  body.view-home .content{height:auto;overflow:auto}   /* 窄屏放弃"锁一屏"，改为可滚动 */
}
