/* ===== 视频首页（2026-11-01）=====
   用户口径：「视频卡得放在主页」「首页 视频 图片 关注 收藏」
             「瀑布流没问题，但要有第一页第二页第三页」
   这一层只做视频 tab 的排版与卡片，不与 style.css 的 .grid 抢样式（那个是图片瀑布流）。 */

/* ---------- tab 切换：视频 / 图片 各显示各的 ---------- */
body.tab-video #filterRow,
body.tab-video #grid,
body.tab-video #pager,
body.tab-video #empty,
body.tab-video #noHit,
body.tab-video #stageMeta,
body.tab-video #imgSearchBox { display: none !important; }
body:not(.tab-video) #vcHome { display: none !important; }

/* ---------- 左栏：生成方式切换 ---------- */
.gmode { display: flex; gap: 5px; margin: 0 0 14px; padding: 4px;
  border-radius: 12px; background: var(--bg2); border: 1px solid var(--line); }
.gmode .gm { flex: 1; padding: 8px 10px; border-radius: 9px; font-size: 13px;
  color: var(--dim); background: transparent; transition: .15s; }
.gmode .gm:hover { color: var(--txt); }
.gmode .gm.on { background: #fff; color: var(--acc); font-weight: 700;
  box-shadow: 0 2px 10px rgba(16, 175, 169, .18); }

/* 视频模式下左侧的面板更紧凑（不显示图片那套） */
body.gen-video .gen-result { display: none !important; }

/* 已选视频卡（左栏） */
.vc-picked { display: flex; gap: 11px; align-items: center; padding: 10px;
  border: 1px solid var(--line); border-radius: 12px; background: var(--card2); }
.vc-picked[data-empty="1"] { justify-content: center; background: #f7fdfc;
  border-style: dashed; min-height: 62px; }
.vc-pick-empty { font-size: 12.5px; color: var(--dim2); }
.vc-picked img { width: 52px; height: 92px; object-fit: cover; border-radius: 8px;
  flex: 0 0 auto; background: #000; }
.vc-picked .vcp-id { font-size: 13px; font-weight: 600; line-height: 1.4;
  overflow: hidden; text-overflow: ellipsis; display: -webkit-box;
  -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.vc-picked .vcp-meta { font-size: 11.5px; color: var(--dim2); margin-top: 3px; }
.vc-picked .vcp-x { margin-left: auto; flex: 0 0 auto; font-size: 12px;
  color: var(--dim2); padding: 4px 8px; border-radius: 8px; }
.vc-picked .vcp-x:hover { background: var(--bg2); color: var(--bad); }

/* 成片结果（左栏） */
.vc-result { margin-top: 12px; border: 1px solid var(--line); border-radius: 12px;
  overflow: hidden; background: #0d1b1a; }
.vc-result video { width: 100%; display: block; }
.vc-result .vcr-bar { display: flex; align-items: center; justify-content: space-between;
  gap: 8px; padding: 9px 12px; background: var(--card2); border-top: 1px solid var(--line); }
.vc-result .vcr-bar span { font-size: 12px; color: var(--dim); }
.vc-result .vcr-bar a { font-size: 12px; color: var(--acc); font-weight: 600;
  text-decoration: none; }

/* ---------- 视频 tab：工具栏 ---------- */
.vch { display: block; }
.vch-tools { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin: 0 0 14px; }
.vch-seg { display: inline-flex; border: 1px solid var(--line); border-radius: 10px;
  overflow: hidden; background: #fff; }
.vch-seg button { padding: 6px 15px; font-size: 13px; color: var(--dim);
  background: transparent; transition: .15s; }
.vch-seg button + button { border-left: 1px solid var(--line); }
.vch-seg button.on { background: var(--acc); color: #fff; font-weight: 600; }
.vch-btn { padding: 7px 14px; border-radius: 10px; border: 1px solid var(--line);
  background: #fff; color: var(--dim); font-size: 13px; transition: .15s; }
.vch-btn:hover { color: var(--acc); border-color: var(--acc2); }
.vch-btn.busy { opacity: .6; pointer-events: none; }
.vch-note { font-size: 12.5px; color: var(--dim2); }

/* ---------- 视频 tab：瀑布流（最短列填充 = 横向优先 + 高度错落）----------
   🔴 2026-11-01 最后一条口径：「匹配完排序改成横向排序 不要出现长方形」。
   两个硬约束必须同时成立：
     (a) 横向顺序 —— 匹配度第 1/2/3/4 名必须在**同一行**、从左到右；
     (b) 不要长方形 —— 卡片高度跟封面原比例走（62 张里 40 张 9:16 竖、14 张横版），
         不许统一裁成等高方块。
   CSS 多列（column-count）做不到 (a)：它**按列**填 DOM，前 24 张会全塞进第 1 列往下排，
   所以之前看到的「顺位是单列」。等高 grid 做得到 (a) 但丢了 (b)（用户：太呆）。
   所以改成 JS 最短列填充（Pinterest 那套），DOM 只当容器：
     · list 顺序 = 视觉顺序（匹配态是匹配度，浏览态是随机序）；
     · 第 i 张落到「当前最矮的列」；起始 4 列高度都是 0 ⇒ 前 4 张必然落在 1/2/3/4 列，
       **横向第一行就是匹配度最高的 4 张**；
     · 之后每张都塞进最矮列 ⇒ 零留白，高度完全按封面原比例，自然有高有矮。
   列数由 JS 按容器宽度算（>1120 四列 / >760 三列 / 否则两列），见 vhome.js:cols()。 */
.vch-grid { display: flex; gap: 14px; align-items: flex-start; }
.vch-col { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: 14px; }
@media (max-width: 760px) { .vch-grid, .vch-col { gap: 10px; } }

.vch-card { position: relative; display: block; width: 100%; margin: 0;
  border-radius: 12px; overflow: hidden; background: #0d1b1a;
  border: 1px solid var(--line); cursor: pointer; transition: .16s; }
.vch-card:hover { border-color: var(--acc2); transform: translateY(-2px);
  box-shadow: 0 8px 22px rgba(16, 175, 169, .16); }
.vch-card.on { border-color: var(--acc); box-shadow: 0 0 0 2px rgba(16, 175, 169, .35); }
/* 高度跟封面走（原比例）：9:16 的竖卡高、16:9 的横卡矮 —— 这就是「有高有矮」的来源。
   aspect-ratio 由 JS 内联写上（接口带 w/h），所以图片没加载完也不会跳位。 */
.vch-card img { display: block; width: 100%; height: auto; background: #0d1b1a; }
.vch-card video { display: block; width: 100%; height: auto; }

.vch-badge { position: absolute; left: 8px; top: 8px; font-size: 11px; font-weight: 600;
  padding: 3px 8px; border-radius: 999px; color: #fff;
  background: rgba(6, 20, 19, .62); backdrop-filter: blur(4px); }
.vch-badge.motion { background: rgba(16, 175, 169, .92); }
.vch-badge.pending { background: rgba(192, 131, 7, .92); }
.vch-hot { position: absolute; right: 8px; top: 8px; font-size: 11px; font-weight: 700;
  padding: 3px 8px; border-radius: 999px; color: #fff;
  background: rgba(6, 20, 19, .62); backdrop-filter: blur(4px);
  font-variant-numeric: tabular-nums; }
.vch-dur { position: absolute; right: 8px; bottom: 8px; font-size: 10.5px; font-weight: 600;
  padding: 2px 6px; border-radius: 6px; background: rgba(6, 20, 19, .7); color: #fff; }
.vch-play { position: absolute; left: 50%; top: 50%; width: 42px; height: 42px;
  margin: -21px 0 0 -21px; border-radius: 50%; background: rgba(255, 255, 255, .86);
  display: grid; place-items: center; opacity: 0; transition: .16s; pointer-events: none; }
.vch-play:before { content: ""; width: 0; height: 0; margin-left: 3px;
  border-left: 12px solid var(--txt); border-top: 8px solid transparent;
  border-bottom: 8px solid transparent; }
.vch-card:hover .vch-play { opacity: 1; }

.vch-empty { padding: 50px 20px; text-align: center; color: var(--dim2); font-size: 14px; }

/* ---------- 分页 ---------- */
.vch-pager { display: flex; align-items: center; justify-content: center; gap: 6px;
  margin: 22px 0 8px; flex-wrap: wrap; }
.vch-pager[hidden] { display: none; }

/* ---------- 视频灯箱 ---------- */
.vclb { position: fixed; inset: 0; z-index: 90; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 12px; padding: 24px;
  background: rgba(6, 20, 19, .93); backdrop-filter: blur(6px); }
.vclb[hidden] { display: none; }
.vclb video { max-height: 76vh; border-radius: 14px; background: #000;
  object-fit: contain; box-shadow: 0 20px 60px rgba(0, 0, 0, .5); }
.vclb-bar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  justify-content: center; }
.vclb-bar .vclb-info { color: #cfe6e4; font-size: 12.5px; }
.vclb-btn { padding: 9px 18px; border-radius: 11px; font-size: 13.5px; font-weight: 600;
  background: rgba(255, 255, 255, .12); color: #fff; border: 1px solid rgba(255, 255, 255, .2); }
.vclb-btn:hover { background: rgba(255, 255, 255, .2); }
.vclb-btn.primary { background: var(--acc); border-color: var(--acc); }
.vclb-btn.primary:hover { background: #0d9d97; }
.vclb-x { position: absolute; right: 20px; top: 16px; font-size: 26px; line-height: 1;
  color: rgba(255, 255, 255, .8); padding: 6px 10px; }
.vclb-x:hover { color: #fff; }


/* ---------- 左栏「图片生成 / 视频生成」两块独立面板（2026-11-01） ----------
   用容器互斥而不是逐个 hidden 子元素：两块面板内容完全不同，
   拆开后各自的显隐只看父级，不会再出现「图片模式下某块没藏住」的错位。 */
.pane { display: block; }
.pane[hidden] { display: none !important; }


/* ---------- 视频模式：把「一键匹配模特」整行换掉（2026-11-01 修 bug） ----------
   #btnMatch / #matchNote 是 app.js 注入到 #mineSlot 里的**图片**匹配按钮。
   视频模式下不 hiding 的话，用户点了会去匹配模特卡，然后因为图片画廊收起、
   renderGallery 在视频 tab 下提前 return，命中数永远显示 0。 */
body.gen-video #btnMatch,
body.gen-video #matchNote { display: none !important; }
#vcMatchRow { margin-top: 10px; }
#vcMatchRow[hidden] { display: none !important; }


/* 顶栏是 sticky 的（高约 64px）：scrollIntoView({block:'start'}) 会把目标行顶到
   视口最上沿、正好被顶栏压住（实测「全部/女/男 最新/最热」那行被切掉一半）。
   给滚动锚点留出这块空隙。 */
#vcHome, #grid, #vcGrid, .side { scroll-margin-top: 76px; }


/* ---------- 视频卡卡片右下角：收藏 / 加参考（2026-11-01 用户要求对标模特卡） ---------- */
.vch-acts { position: absolute; right: 8px; bottom: 8px; display: flex; gap: 6px;
  opacity: 0; transition: .16s; }
.vch-card:hover .vch-acts, .vch-card.on .vch-acts, .vch-acts:focus-within { opacity: 1; }
.vch-act { width: 30px; height: 30px; border: 1px solid rgba(255, 255, 255, .62);
  border-radius: 50%; display: grid; place-items: center; cursor: pointer;
  background: rgba(8, 10, 14, .78); color: #fff; font-size: 15px; line-height: 1;
  box-shadow: 0 2px 10px rgba(0, 0, 0, .5); backdrop-filter: blur(6px); transition: .16s; }
.vch-act svg { width: 15px; height: 15px; display: block; fill: none;
  stroke: currentColor; stroke-width: 2.1; stroke-linejoin: round; }
.vch-act:hover { transform: scale(1.09); border-color: #ff5a7a; color: #ff9db1; }
.vch-act.on { background: #e8385e; border-color: #e8385e; color: #fff; }
.vch-act.on svg { fill: #fff; stroke: #fff; }
.vch-act.add { font-size: 17px; font-weight: 400; }
.vch-act.add:hover { border-color: var(--acc2); color: var(--acc2); }
/* 触屏没有 hover：按钮常显，否则根本点不到 */
@media (hover: none) { .vch-acts { opacity: 1; } }
/* 时长挪到左下，把右下让给按钮 */
.vch-dur { left: 8px; right: auto; }

/* ---------- 收藏 tab 里的视频卡区块 ---------- */
.fav-vch { margin: 4px 0 22px; }
.fav-vch[hidden] { display: none !important; }
.favv-head { display: flex; align-items: baseline; gap: 10px; margin: 0 0 12px;
  font-size: 14px; font-weight: 600; color: var(--txt); }
.favv-head em { font-style: normal; font-weight: 400; font-size: 12px; color: var(--dim2); }
.favv-tip { margin-left: auto; font-size: 11.5px; color: var(--dim2); }
@media (max-width: 820px) { .favv-tip { display: none; } }

/* 灯箱里的收藏按钮 */
.vclb-bar .vclb-btn.on { background: #e8385e; border-color: #e8385e; color: #fff; }

/* ---------- 视频模式：没选卡 ⇒ 「生成视频」不可点 ----------
   2026-11-01 用户：「用户没有选择视频卡的时候是不能点击生成视频的，这是 bug」。
   逻辑在 vhome.js:syncGenBtn()（noPick ⇒ disabled）；这里只管视觉 ——
   跟 style.css 里风控拦住时的 .blocked 用同一套灰化，用户一眼看出点不了。
   ⚠️ 只在 body.gen-video 下生效：图片模式走 app.js 的 .blocked（不禁用、点了给提示），
      两套口径不能互相污染。 */
body.gen-video .gen-btn:disabled,
body.gen-video .gen-btn:disabled:hover {
  filter: grayscale(.85) brightness(.7);
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}
body.gen-video .gen-btn:disabled .spark { opacity: .35; }
